2010 07 Generator Pakietów Scapy

background image

7/2010

14

OBRONA

Scapy

www.hakin9.org

15

N

a wszystkie powyższe pytania możemy odpo-

wiedzieć: tak – mając do dyspozycji darmowe

oprogramowanie scapy. Jedną możliwości ofe-

rowanych przez to narzędzie jest generowanie pakie-

tów – przy czym, w odróżnieniu od innych znanych ge-

neratorów pakietów (takich jak: sendip, nemesis, netdu-

de, czy hping), scapy:

• posiada bardzo dużą bazę obsługiwanych protoko-

łów,

• jest prosty i szybki w obsłudze,

• zapewnia użytkownikowi wysoką elastyczność pod-

czas korzystania z oferowanej przez siebie funkcjo-

nalności,

• jest aktywnie rozwijany,

• oferuje bardzo szerokie możliwości skryptowania,

• zapewnia relatywnie proste możliwości implemen-

tacji obsługi zupełnie nowego rodzaju pakietów

i protokołów (wymagana jest przy tym jednak zna-

jomość języka python).

Sam autor narzędzia twierdzi, że jest ono w stanie

zastąpić takie aplikacje jak: hping, 85% funkcjonal-

ności nmap-a, arpspoof, arp-sk, arping, tcpdump, te-

thereal czy p0f. Nie będziemy polemizować z tym

twierdzeniem – zaprezentujemy za to praktyczne

przykłady wykorzystania scapy, niech one same bę-

dą komentarzem do możliwości tego oprogramowa-

nia.

ls() – wyświetlenie obsługiwanych pakietów

Scapy w wersji 2.1.0 obsługuje przeszło 300 rodza-

jów pakietów, przy czym pakiet rozumiemy tutaj bardzo

ogólnie – jako pewien odpowiednio sformatowany zbiór

danych, który może być przesyłany przez sieć (stosow-

ne formatowanie określa odpowiedni protokół siecio-

wy). Na Listingu 1 prezentujemy niewielki fragment li-

sty pakietów zaimplementowanych w scapy, przy czym

dostępne są dodatkowe pluginy uzupełniające tę listę

(przykład – protokół OSPF).

ls() – wyświetlenie szczegółów budowy

pakietu

Przed utworzeniem pakietu w scapy warto zapoznać

się z jego strukturą (Listing 2).

W pierwszej kolumnie podawana jest nazwa każdego

pola, w drugiej jego typ, a w trzeciej – wartość domyśl-

na przy tworzeniu nowego pakietu.

Tworzenie nowego pakietu

W scapy jest to prosta operacja:

>>> p = ICMP()

Wyświetlenie szczegółów pakietu

W przykładzie z Listingu 3 jako domyślny typ ICMP został

ustawiony echo-request (znany z popularnego ping-a).

Jeśli przy budowie pakietu chcielibyśmy podać inny typ,

możemy zrobić to w sposób przedstawiony na Listingu 4.

Generator Pakietów Scapy

Czy istnieje łatwy sposób na wygenerowanie niemal

dowolnych pakietów? Czy można bez większych trudności

zmodyfikować przechwycony pakiet i wysłać go ponownie?

Czy nieskomplikowanym zadaniem jest przygotowanie

fuzzera protokołu sieciowego?

Michał Sajdak

Dowiesz się:

• jak posługiwać się oprogramowaniem scapy,
• jak generować (niemal) dowolny ruch sieciowy,
• jak wykonać fuzzing protokołu sieciowego.

Powinieneś wiedzieć:

• powinieneś znać podstawowe protokoły wykorzystywane

w sieci Internet,

• powinieneś znać dowolny język programowania.

background image

7/2010

14

OBRONA

Scapy

www.hakin9.org

15

Wygenerowanie grupy pakietów

Spróbujmy tym razem wygenerować nie jeden pakiet

– a całą ich grupę, mianowicie 19 pakietów ICMP o polu

type, przyjmującym wartości od 0 do 18 (pozostałe po-

la przyjmą wartości domyślne ustalone w scapy). Tym

razem skorzystamy z funkcji

sr()

(jej nazwa to skrót

od send-receive), wysyłającej w warstwie 3. Funkcja

ta zwraca dwie wartości: pakiety z wysyłanego zbioru,

które doczekały się odpowiedzi oraz te, na które odpo-

wiedź nie przyszła – patrz Listing 12.

Proste skanowanie portów

Wykorzystując wiedzę z powyższego przykładu, wy-

konajmy prosty skaner portów (Listing 13). W naszym

przypadku będzie to wysłanie 4 pakietów TCP z usta-

wioną flagą Syn, na cztery różne porty.

W pętli powyżej przeglądamy całą zwróconą tabli-

cę o nazwie a. Każdy element tej tablicy posiada dwa

kolejne elementy – pakiet wysłany oraz otrzymana na

niego odpowiedź (w pętli odpowiadają tym elementom

zmienne

req

oraz

resp

). Jeśli odpowiedź jest pakietem

TCP z flagą SA, oznacza to że badany port jest otwarty

(otrzymaliśmy segment TCP z flagami SA w odpowiedzi

na segment z flagą S).

Podsłuchiwanie ruchu oraz modyfikacja

komunikacji sieciowej

Aby podsłuchać ruch, możemy skorzystać z wbudowa-

nej w scapy funkcji

sniff()

, możemy również wczytać

zbiór pakietów w formacie libpcap – funkcja

rdpcap()

.

Na Listingu 14 zauważmy, że przechwycony przez

nas pakiet IP zawiera początkowo poprawną sumę kon-

trolną, jednak po zmianie docelowego adresu IP, suma

kontrolna będzie błędna! Dlatego, aby wysłać pakiet

bez błędów, poprosiliśmy scapy o automatyczne wyge-

nerowanie prawidłowej sumy za nas, podstawiając jej

wartość na pustą:

i[IP].chksum=None

Odczytanie podsłuchanych pakietów ze zrzutu w for-

macie libpcap jest równie proste (Listing 15.)

Przy okazji warto również wspomnieć o funkcji

wrpcap()

– zapisującej pakiety w formacie libpcap. Ta-

ka możliwość może okazać się przydatna, jeśli chcie-

libyśmy wybrane pakiety poddać obróbce lub analizie

w innym, zewnętrznym narzędziu. Dalej (Listing 16)

prezentujemy przykład sfragmentowania komunikacji

IP, z wykorzystaniem narzędzia tcprewrite, które po-

siada wkompilowaną obsługę mechanizmu fragroute.

Fuzzing protokołów sieciowych

W skrócie, fuzzing protokołów sieciowych, polega na

wygenerowaniu pakietów niekoniecznie zgodnych ze

specyfikacją protokołu oraz sprawdzeniu w jaki sposób

W przykładzie na Listingu 4 skorzystaliśmy z poda-

nia typu bezpośrednio lub za pośrednictwem mnemoni-

ka. Mnemoniki dla pól typu enum możemy wyświetlić za

pomocą składni: pakiet.nazwa_pola.i2s

Łączenie pakietów

Jak wiemy, pełen prawidłowy pakiet ICMP, składa się

z kilku warstw: ramka (na potrzebny artykułu nazywamy

pakietem) warstwy drugiej modelu OSI, pakiet IP oraz

pakiet ICMP. Złóżmy dwa pakiety – IP oraz wcześniej

stworzony ICMP (Listing 4, Listing 5). Ramka etherne-

towa zostanie dodana później – już przez scapy.

Zauważmy, że wszystkie pola zostały wypełnione

zgodnie z wartościami domyślnymi (polecenie

ls(typ_

pakietu)

) – a dodatkowo pole IP.proto zostało wypełnio-

ne poprawnie – tj. pakiet protokołu IP w powyższym pa-

kiecie transportuje pakiet protokółu ICMP. Zwróćmy rów-

nież uwagę na pola chksum – przyjęły one wartość None.

W tym przypadku oznacza to, że sumy kontrolne zosta-

ną wyliczone na podstawie tego jak zbudujemy pakiet –

a wykona to za nas scapy. Aktualną sumę kontrolną moż-

na zobaczyć wykorzystując metodę

show2

(Listing 6).

Przy okazji wspomnijmy, że dostępne w danej kla-

sie zmienne i metody możemy uzyskać poleceniem

dir

(wynik tego polecania, widoczny na Listingu 7, został

skrócony w celu ułatwienia prezentacji wyników).

Z kolei pomoc dotyczącą interesującej nas metody

możemy uzyskać poleceniem

help()

– Listing 8.

Modyfikacja zawartości pakietu

Aby zmodyfikować pole w interesującej nas warstwie,

stosujemy notację:

pakiet[warstwa].pole = wartość

.

Na przykład:

p1[IP].dst = '192.168.0.1'

Wysłanie pakietu oraz odebranie odpowiedzi

Istnieje kilka funkcji wysyłających oraz odbierających

pakiety – można je poznać wydając polecenie

lsc()

oraz

help

(nazwa_funkcji). W przykładzie poniżej wy-

korzystamy funkcję

sr1()

, która wysyła pakiety w war-

stwie 3 modelu OSI (tj. ramka warstwy drugiej zostanie

za nas uzupełniona) oraz odbiera pierwszy pakiet odpo-

wiedzi (Listing 9).

Zauważmy, że nie musieliśmy uzupełniać pakietu

o ramkę ethernetową, tę pracę wykonała za nas funk-

cja

sr1()

. Jeśli chcielibyśmy jednak kontrolować dane

również w warstwie 2, musielibyśmy skorzystać z funk-

cji

srp1()

oraz uzupełnić pakiet o ramkę Ethernet. Przy

założeniu, że w zmiennej i zdefiniowany mamy pakiet

IP()/ICMP(), dołożenie ramki ethernetowej wygląda tak

jak na Listingu 10.

Dla dalszego zobrazowania możliwości oferowanych

przez scapy, prezentujemy wynik wspomnianego wyżej

polecenia

lsc()

– widoczny na Listingu 11.

background image

7/2010

16

OBRONA

Scapy

www.hakin9.org

17

na taką komunikację zareaguje docelowy system. Przy-

kładowo, niepoprawnym pakietem może być pakiet IP

z ustaloną nietypową wartością w polu IP.version. Czę-

sto w ten sposób wykryta może być błędna obsługa da-

nego pakietu przez docelowy system, co niekiedy koń-

czy się jego kompromitacją (patrz np. pracę Wifi Advan-

ced Fuzzing @ Blackhat EU 07, pokazującą podatno-

ści umożliwiające wykonanie wrogiego kodu na bez-

przewodowym punkcie dostępowym z uprawnieniami

jądra systemu operacyjnego – potencjalnie nawet bez

konieczności uwierzytelnienia się w urządzeniu access

point!). Najprostsza postać realizacji fuzzingu w scapy

wygląda tak jak na Listingu 17.

Odpowiadający takiej komunikacji, zrzut wykonany

przy pomocy tcpdump-a wygląda z kolei tak jak na Li-

stingu 18.

Analogicznie do przykładu pokazanego na Listingu

18, istnieje możliwość ręcznego podstawienia danego

pola, nie wartością, a funkcją, zwracającą wartość loso-

wą (Listing 19).

Prosty program w pythonie

Jako ilustrację do możliwości skryptowania z wykorzy-

staniem scapy, przedstawiamy szkic bardzo prostego

skanera portów napisanego w pythonie. Komentarzem

do skryptu niech będzie sam kod źródłowy, jak na Li-

stingu 20.

Podsumowanie

Dociekliwych Czytelników zachęcamy do własnego

eksperymentowania z oprogramowaniem scapy. Mamy

nadzieję, że pokazaliśmy moc tego narzędzia, którego

rozmaite zastosowania są ograniczone niemal tylko po-

mysłowością użytkownika.

Listing 1. Typy pakietów dostępne w scapy

securitum-t1:~# scapy
Welcome to Scapy (2.1.0)
>>> ls()

ARP : ARP
ASN1_Packet : None
BOOTP : BOOTP
CookedLinux : cooked linux
DHCP : DHCP options
DHCP6 : DHCPv6 Generic Message)
...
DNS : DNS
DNSQR : DNS Question Record
DNSRR : DNS Resource Record
DUID_EN : DUID - Assigned by Vendor Based on

Enterprise Number

Dot11 : 802.11
Dot11ATIM : 802.11 ATIM
Dot11AssoReq : 802.11 Association Request
Dot11AssoResp : 802.11 Association Response
...
Dot1Q : 802.1Q
Dot3 : 802.3
EAP : EAP
EAPOL : EAPOL
Ether : Ethernet
GPRS : GPRSdummy
GRE : GRE
...
IP : IP
IPOption : None
IPOption_Address_Extension : IP Option Address

Extension

...
PPP : PPP Link Layer
PPP_ECP : None
PPP_ECP_Option : PPP ECP Option
PPP_ECP_Option_OUI : PPP ECP Option
...
RIP : RIP header
RIPEntry : RIP entry
RTP : RTP
RadioTap : RadioTap dummy
Radius : Radius
Raw : Raw
RouterAlert : Router Alert
STP : Spanning Tree Protocol
SebekHead : Sebek header
TCP : TCP
TCPerror : TCP in ICMP
TFTP : TFTP opcode
...

MICHAŁ SAJDAK

Dyrektor ds. Rozwoju w �rmie Securi-
tum. Prowadzi szkolenia o tematyce
związanej z bezpieczeństwem IT oraz
realizuje testy penetracyjne systemów
IT. Posiadacz certy�katu CISSP.
Kontakt z autorem:
michal.sajdak@securitum.pl

W Sieci

http://www.secdev.org/projects/scapy/,

http://www.dirk-loss.de/scapy-doc/,

http://trac.secdev.org/scapy/wiki/OSPF,

http://freshmeat.net/projects/sendip/,

http://nemesis.sourceforge.net/,

http://netdude.sourceforge.net/,

http://www.hping.org/,

http://www.blackhat.com/presentations/bh-europe-07/

Butti/Presentation/bh-eu-07-Butti.pdf.

background image

7/2010

16

OBRONA

Scapy

www.hakin9.org

17

Listing 2. Struktura pakietu w scapy

>>> ls(ICMP)
type : ByteEnumField = (8)
code : MultiEnumField = (0)
chksum : XShortField = (None)
id : ConditionalField = (0)
seq : ConditionalField = (0)
ts_ori : ConditionalField = (50705671)
ts_rx : ConditionalField = (50705671)
ts_tx : ConditionalField = (50705671)
gw : ConditionalField = ('0.0.0.0')
ptr : ConditionalField = (0)
reserved : ConditionalField = (0)
addr_mask : ConditionalField = ('0.0.0.0')
unused : ConditionalField = (0)

Listing 3. Wyświetlenie zawartości pakietu

>>> p.show()
###[ ICMP ]###
type= echo-request
code= 0
chksum= None
id= 0x0
seq= 0x0

Listing 4. Stworzenie pakietu ICMP

>>> p = ICMP(type=0)
>>> ICMP.type.i2s
{0: 'echo-reply', 3: 'dest-unreach', 4: 'source-

quench',

5: 'redirect', 8: 'echo-request', 9: 'router-

advertisement',

10: 'router-solicitation', 11: 'time-exceeded',
12: 'parameter-problem', 13: 'timestamp-request',
14: 'timestamp-reply', 15: 'information-request',
16: 'information-response', 17: 'address-mask-

request',

18: 'address-mask-reply'}
>>> p = ICMP(type='information-request')

Listing 5. Łączenie pakietów

>>> p1 = IP()/p
>>> p1.show()
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= icmp
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
###[ ICMP ]###
type= echo-request
code= 0
chksum= None
id= 0x0
seq= 0x0

Listing 6. Wynik metody show2()

>>> i.show2()
###[ IP ]###
version= 4L
...
chksum= 0x7cde
...
\options\
###[ ICMP ]###
...
chksum= 0xf7ff
>>>

Listing 7. Wyświetlenie zmiennych i metod dostępnych w

danej klasie

>>> dir(p)
['__class__', '__contains__', '__delattr__', '__

delitem__', '__dict__', [...]

'add_payload', 'add_underlayer', 'aliastypes',

'answers', 'build', [...]

'show', 'show2', 'show_indent', 'sprintf',

'summary', 'time', [...]

background image

7/2010

18

OBRONA

Scapy

www.hakin9.org

19

Listing 8. Wyświetlenie pomocy dla wybranej metody

>>>
help(p.show2)
Help on method show2 in module scapy.packet:

show2(self) method of scapy.layers.inet.ICMP instance
Prints a hierarchical view of an assembled version of the packet,
so that automatic fields are calculated (checksums, etc.)

Listing 9. Podstawowa metoda wysłania pakietu oraz

odebrania odpowiedzi – sr1()

>>> r = sr1(p1)
Begin emission:
Finished to send 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0

packets

>>> r.show()
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 28
id= 30733
flags=
frag= 0L
ttl= 64
proto= icmp
chksum= 0x8106
src= 192.168.0.1
dst= 192.168.0.124
\options\
###[ ICMP ]###
type= echo-reply
code= 0
chksum= 0xffff
id= 0x0
seq= 0x0
###[ Padding ]###
load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\

x00\x00\x00\x00\x00\x00\x00\x00\
x00'

Listing 10. Podstawowa metoda wysłania pakietu oraz

odebrania odpowiedzi - srp1()

>>> i2 = Ether(dst='00:19:5b:dc:b7:ec')/i
>>> i2.show()
###[ Ethernet ]###
dst= 00:19:5b:dc:b7:ec
src= 00:0c:29:7f:48:3f
type= 0x800
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= icmp
chksum= None
src= 192.168.0.124
dst= 192.168.0.1
\options\
###[ ICMP ]###
type= echo-request
code= 0
chksum= None
id= 0x0
seq= 0x0
>>> r2 = srp1(i2)
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0

packets

background image

7/2010

18

OBRONA

Scapy

www.hakin9.org

19

Listing 11. Wynik polecenia lsc()

arpcachepoison: Poison target's cache with (your MAC,victim's IP) couple
arping : Send ARP who-has requests to determine which hosts are up
defrag : defrag(plist) -> ([not fragmented], [defragmented],
defragment : defrag(plist) -> plist defragmented as much as possible
dyndns_del : Send a DNS delete message to a nameserver for "name"
etherleak : Exploit Etherleak flaw
fragment : Fragment a big IP datagram
fuzz : Transform a layer into a fuzzy layer by replacing some
default values by random objects
getmacbyip : Return MAC address corresponding to a given IP address
hexdiff : Show differences between 2 binary strings
ls : List available layers, or infos on a given layer
rdpcap : Read a pcap file and return a packet list
send : Send packets at layer 3
sendp : Send packets at layer 2
sendpfast : Send packets at layer 2 using tcpreplay for performance
sniff : Sniff packets
split_layers : Split 2 layers previously bound
sr : Send and receive packets at layer 3
sr1 : Send packets at layer 3 and return only the first answer
srflood : Flood and receive packets at layer 3
srloop : Send a packet at layer 3 in loop and print
the answer each time
srp : Send and receive packets at layer 2
srp1 : Send and receive packets at layer 2 and return only
the first answer
srpflood : Flood and receive packets at layer 2
srploop : Send a packet at layer 2 in loop and print the answer
each time
traceroute : Instant TCP traceroute
tshark : Sniff packets and print them calling pkt.show(),
a bit like text wireshark
wireshark : Run wireshark on a list of packets
wrpcap : Write a list of packets to a pcap file

Listing 12. Generowanie grupy pakietów

>>> pi = IP(dst='192.168.0.1')/ICMP(type=(0,18))
>>> answered,uanswered = sr(pi)
Begin emission:
...*.Finished to send 19 packets.
.......^C
Received 12 packets, got 1 answers, remaining 18 packets
>>> answered.show()
0000 IP / ICMP 192.168.0.124 > 192.168.0.1 echo-request 0
==> IP / ICMP 192.168.0.1 > 192.168.0.124 echo-reply 0 / Padding
>>> uanswered.show()
0000 IP / ICMP 192.168.0.124 > 192.168.0.1 dest-unreach network-unreachable
0001 IP / ICMP 192.168.0.124 > 192.168.0.1 source-quench 0
0002 IP / ICMP 192.168.0.124 > 192.168.0.1 redirect network-redirect
0003 IP / ICMP 192.168.0.124 > 192.168.0.1 time-exceeded ttl-zero-during-transit
0004 IP / ICMP 192.168.0.124 > 192.168.0.1 parameter-problem ip-header-bad
0005 IP / ICMP 192.168.0.124 > 192.168.0.1 1 0

background image

7/2010

20

OBRONA

Scapy

www.hakin9.org

21

0006 IP / ICMP 192.168.0.124 > 192.168.0.1 2 0
0007 IP / ICMP 192.168.0.124 > 192.168.0.1 6 0
0008 IP / ICMP 192.168.0.124 > 192.168.0.1 7 0
0009 IP / ICMP 192.168.0.124 > 192.168.0.1 router-advertisement 0
0010 IP / ICMP 192.168.0.124 > 192.168.0.1 router-solicitation 0
0011 IP / ICMP 192.168.0.124 > 192.168.0.1 echo-reply 0
0012 IP / ICMP 192.168.0.124 > 192.168.0.1 timestamp-request 0
0013 IP / ICMP 192.168.0.124 > 192.168.0.1 timestamp-reply 0
0014 IP / ICMP 192.168.0.124 > 192.168.0.1 information-request 0
0015 IP / ICMP 192.168.0.124 > 192.168.0.1 information-response 0
0016 IP / ICMP 192.168.0.124 > 192.168.0.1 address-mask-request 0
0017 IP / ICMP 192.168.0.124 > 192.168.0.1 address-mask-reply 0

Listing 13. Proste skanowanie portów

>>> packets = IP(dst='192.168.0.1')/TCP(flags='S',dport=[22,23,80,515])
>>> a,ua=sr(packets)
Begin emission:
**..Finished to send 4 packets.
*.*
Received 7 packets, got 4 answers, remaining 0 packets
>>> a.show()
0000 IP / TCP 192.168.0.124:ftp_data > 192.168.0.1:ssh S
==> IP / TCP 192.168.0.1:ssh > 192.168.0.124:ftp_data RA / Padding
0001 IP / TCP 192.168.0.124:ftp_data > 192.168.0.1:telnet S
==> IP / TCP 192.168.0.1:telnet > 192.168.0.124:ftp_data RA / Padding
0002 IP / TCP 192.168.0.124:ftp_data > 192.168.0.1:www S
==> IP / TCP 192.168.0.1:www > 192.168.0.124:ftp_data SA / Padding
0003 IP / TCP 192.168.0.124:ftp_data > 192.168.0.1:printer S
==> IP / TCP 192.168.0.1:printer > 192.168.0.124:ftp_data SA / Padding

>>> for req,resp in a:
... print "port = "+str(req.dport)
... resp.sprintf('%TCP.flags%')
...
port = 22
'RA'
port = 23
'RA'
port = 80
'SA'
port = 515
'SA'

Listing 14. Podsłuchiwanie ruchu oraz mody�kacja komunikacji sieciowej

>>> res = sniff()
^C>>> res.show()
0000 Ether / IP / TCP 192.168.0.124:ssh > 192.168.0.107:3242 PA / Raw
0001 Ether / IP / TCP 192.168.0.107:3242 > 192.168.0.124:ssh A
0002 Ether / ARP who has 192.168.0.1 says 192.168.0.124
0003 Ether / ARP is at 00:19:5b:dc:b7:ec says 192.168.0.1 / Padding
0004 Ether / IP / UDP / DNS Qry "www.onet.pl."
0005 Ether / IP / UDP / DNS Ans "213.180.146.27"
0006 Ether / IP / ICMP 192.168.0.124 > 213.180.146.27 echo-request 0 / Raw

background image

7/2010

20

OBRONA

Scapy

www.hakin9.org

21

0007 Ether / IP / ICMP 213.180.146.27 > 192.168.0.124 echo-reply 0 / Raw
0008 Ether / IP / UDP / DNS Qry "27.146.180.213.in-addr.arpa."
0009 Ether / IP / UDP / DNS Ans "s4.m1r2.onet.pl."
0010 Ether / IP / ICMP 192.168.0.124 > 213.180.146.27 echo-request 0 / Raw
0011 Ether / IP / ICMP 213.180.146.27 > 192.168.0.124 echo-reply 0 / Raw
0012 Ether / IP / UDP / DNS Qry "27.146.180.213.in-addr.arpa."
0013 Ether / IP / UDP / DNS Ans "s4.m1r2.onet.pl."
0014 Ether / IP / ICMP 192.168.0.124 > 213.180.146.27 echo-request 0 / Raw
0015 Ether / IP / ICMP 213.180.146.27 > 192.168.0.124 echo-reply 0 / Raw
0016 Ether / IP / UDP / DNS Qry "27.146.180.213.in-addr.arpa."
0017 Ether / IP / UDP / DNS Ans "s4.m1r2.onet.pl."
>>> i = res[6]
>>> i.show()
###[ Ethernet ]###
dst= 00:19:5b:dc:b7:ec
src= 00:0c:29:7f:48:3f
type= 0x800
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 84
id= 0
flags= DF
frag= 0L
ttl= 64
proto= icmp
chksum= 0x11b5
src= 192.168.0.124
dst= 213.180.146.27
\options\
###[ ICMP ]###
type= echo-request
code= 0
chksum= 0x1dbc
id= 0xa30d
seq= 0x1
###[ Raw ]###
load= '\xf3R\xd8K~\x93\x02\x00\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\

x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'

>>> i[IP].dst='87.98.189.148'
>>> i[IP].chksum=None
>>> r = srp1(i)
Begin emission:
Finished to send 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> r.show()
###[ Ethernet ]###
dst= 00:0c:29:7f:48:3f
src= 00:19:5b:dc:b7:ec
type= 0x800
###[ IP ]###
version= 4L

background image

7/2010

22

OBRONA

Scapy

www.hakin9.org

23

ihl= 5L
tos= 0x0
len= 84
id= 40889
flags=
frag= 0L
ttl= 0
proto= icmp
chksum= 0x44d5
src= 87.98.189.148
dst= 192.168.0.124
\options\
###[ ICMP ]###
type= echo-reply
code= 0
chksum= 0x25bc
id= 0xa30d
seq= 0x1
###[ Raw ]###
load= '\xf3R\xd8K~\x93\x02\x00\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\

x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'

Listing 15. Odczytanie ruchu z pliki w formacie libpcap

securitum-t1:~# tcpdump -n -s 0 -i eth0 -U -w out.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
^C20 packets captured
21 packets received by filter

securitum-t1:~# scapy
Welcome to Scapy (2.1.0)
>>> packets = rdpcap('out.pcap')
>>> packets.show()
0000 Ether / IP / TCP 192.168.0.124:ssh > 192.168.0.107:3242 PA / Raw
0001 Ether / IP / TCP 192.168.0.124:ssh > 192.168.0.107:3242 PA / Raw
0002 Ether / IP / TCP 192.168.0.107:3242 > 192.168.0.124:ssh A / Padding
0003 Ether / IP / UDP / DNS Qry "www.onet.pl."
0004 Ether / IP / UDP / DNS Ans "213.180.146.27"
0005 Ether / IP / ICMP 192.168.0.124 > 213.180.146.27 echo-request 0 / Raw
0006 Ether / IP / ICMP 213.180.146.27 > 192.168.0.124 echo-reply 0 / Raw
0007 Ether / IP / UDP / DNS Qry "27.146.180.213.in-addr.arpa."
0008 Ether / IP / UDP / DNS Ans "s4.m1r2.onet.pl."
0009 Ether / ARP who has 192.168.0.124 says 192.168.0.107 / Padding
0010 Ether / ARP is at 00:0c:29:7f:48:3f says 192.168.0.124
0011 Ether / IP / ICMP 192.168.0.124 > 213.180.146.27 echo-request 0 / Raw
0012 Ether / IP / ICMP 213.180.146.27 > 192.168.0.124 echo-reply 0 / Raw
0013 Ether / IP / UDP / DNS Qry "27.146.180.213.in-addr.arpa."
0014 Ether / IP / UDP / DNS Ans "s4.m1r2.onet.pl."
0015 Ether / IP / ICMP 192.168.0.124 > 213.180.146.27 echo-request 0 / Raw
0016 Ether / IP / ICMP 213.180.146.27 > 192.168.0.124 echo-reply 0 / Raw
0017 Ether / IP / UDP / DNS Qry "27.146.180.213.in-addr.arpa."
0018 Ether / IP / UDP / DNS Ans "s4.m1r2.onet.pl."
0019 Ether / IP / TCP 192.168.0.107:3242 > 192.168.0.124:ssh PA / Raw

background image

7/2010

22

OBRONA

Scapy

www.hakin9.org

23

Listing 16. Wykorzystanie funkcji wrpcap()

>>> pkt = Ether()/IP(dst='192.168.0.1')/ICMP()/("X"*100)
>>> wrpcap('to_fragment.pcap', pkt)

securitum-t2:~# tcprewrite --infile=to_fragment.pcap
--outfile=fragmented.pcap --fragroute=/usr/local/etc/fragroute.conf
192.168.0.104 > 192.168.0.1: icmp: type 8 code 0 (frag 1:24@0+)
192.168.0.104 > 192.168.0.1: (frag 1:24@24+)
192.168.0.104 > 192.168.0.1: (frag 1:24@48+) [delay 0.001 ms]
192.168.0.104 > 192.168.0.1: (frag 1:12@96) [delay 0.001 ms]
192.168.0.104 > 192.168.0.1: (frag 1:24@72+) [delay 0.001 ms]
192.168.0.104 > 192.168.0.1: (frag 1:24@72+)
192.168.0.104 > 192.168.0.1: icmp: type 65 code 71 (frag 1:24@0+) [delay 0.001 ms]
192.168.0.104 > 192.168.0.1: (frag 1:12@96)
192.168.0.104 > 192.168.0.1: (frag 1:24@24+) [delay 0.001 ms]
192.168.0.104 > 192.168.0.1: (frag 1:24@48+)
securitum-t2:~# scapy
>>> f = rdpcap('fragmented.pcap')
>>> f.show()
0000 Ether / IP / ICMP 192.168.0.104 > 192.168.0.1 echo-request 0 / Raw
0001 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:3 / Raw
0002 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:6 / Raw
0003 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:12 / Raw
0004 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:9 / Raw
0005 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:9 / Raw
0006 Ether / IP / ICMP 192.168.0.104 > 192.168.0.1 65 71 / Raw
0007 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:12 / Raw
0008 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:3 / Raw
0009 Ether / 192.168.0.104 > 192.168.0.1 icmp frag:6 / Raw

Listing 17. Podstawowa metoda fuzzingu protokołu sieciowego

>>> p = IP(dst='192.168.0.1')/ICMP()
>>> p = fuzz(p)
>>> p.show()
###[ IP ]###
version=

<

RandNum

>

ihl= None
tos= 31
len= None
id=

<

RandShort

>

flags=
frag= 0
ttl=

<

RandByte

>

proto= icmp
chksum= None
src= 192.168.0.124
dst= 192.168.0.1
\options\
###[ ICMP ]###
type=

<

RandByte

>

code= 207
chksum= None
unused=

<

RandInt

>

background image

7/2010

24

OBRONA

>>> send(p,loop=1)
................................................................................................................

Listing 18. Fuzzing protokołu sieciowego widziany w tcpdump()

securitum-t1:~# tcpdump -v -n -i eth0 icmp
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

18:37:00.152656 IP7 (tos 0x8b,CE, ttl 63, id 19269, offset 0, flags [+, rsvd], proto ICMP (1), length 28)

192.168.0.124 > 192.168.0.1: ICMP type-#170, length 8

IP5 [|ip]
18:37:00.156424 IP14 (tos 0x99,ECT(1), ttl 128, id 46969, offset 0, flags [+, DF, rsvd], proto ICMP (1), length

28) 192.168.0.124 > 192.168.0.1: ICMP type-#180, length 8

IP5 [|ip]
18:37:00.159799 IP9 (tos 0x7a,ECT(0), ttl 114, id 53503, offset 0, flags [DF], proto ICMP (1), length 28)

192.168.0.124 > 192.168.0.1: ICMP type-#105, length 8

IP5 [|ip]
18:37:00.163474 IP14 (tos 0x18, ttl 163, id 24203, offset 0, flags [+, rsvd], proto ICMP (1), length 28)

192.168.0.124 > 192.168.0.1: ICMP type-#61, length 8

IP5 [|ip]
18:37:00.167175 IP5 (tos 0x1,ECT(1), ttl 13, id 59219, offset 0, flags [none], proto ICMP (1), length 28)

192.168.0.124 > 192.168.0.1: ICMP type-#180, length 8

IP5 [|ip]
...

Listing 19. Ustawienie pola w pakiecie funkcją zwracającą

wartość losową

>>> i = IP()/ICMP()
>>> i[IP].version = RandShort()
>>> i.show()
###[ IP ]###
version=

<

RandShort

>

ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= icmp
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
###[ ICMP ]###
type= echo-request
code= 0
chksum= None
id= 0x0
seq= 0x0

Listing 20. Prosty skaner portów napisany w pythonie, z

wykorzystaniem scapy. scapy-scanner.py (uruchomienie:

python scapy-scanner.py)

from scapy.all import *

# zakres portow do skanowania
ports = (1,1024)
# cel skanowania
dst_ip = '192.168.0.1'

# definicja pakietow
syn_packets = IP(dst=dst_ip)/TCP(flags='S',dport=po

rts)

# wyslanie pakietow oraz odebranie odpowiedzi
answered, uanaswered = sr(syn_packets, verbose=0)

# analiza odpowiedzi
for request, response in answered:
response_flags = response.sprintf('%TCP.flag

s%')

if response_flags == 'SA':
print "Port TCP: " +

str(request.dport) + " otwarty"


Wyszukiwarka

Podobne podstrony:
2010 07 Szkoła konstruktorów klasa II
Arot 2010 07 2010 id 69283 Nieznany
SERWIS 2010.07.05
2010 07 Płytki drukowane metoda fotochemiczna
kyoritsu 4140 103892 KARTA 2010 07 16 1
EPII zarzadzanie aktywami zapasy 2010.07.01
2010 07 Old Time Player
2010 regional general pl
EPII zarzadzanie aktywami zapasy 2010 07 01
67 NW 07 Generator drgan
2010 07 HAS House's Automated System
2010 07 Szkoła konstruktorów klasa III
2010 07 22 Rozp MON Ćwiczenia wojskowe
2010 07 Ćwiczenie 4 Whisper posłuchiwacz szeptów
2010 07 09 Kalendarz Histmag org
Nowy Gornik 01 2010 07
07 Generatory elektroniczne, ZSS
bsn 2010 07 040
Nafta Gaz 2010 07 05

więcej podobnych podstron