lost and found ( for me ? )

Showing posts with label python-dpkt. Show all posts
Showing posts with label python-dpkt. Show all posts

parsing HTTP pcap w/ python-dpkt (/usr/share/pyshared/dpkt/pcap.py )

I  just followed the following instructions. many thx XD


prepare pcap file ( HTTP )
root@bt:~# tshark /root/http.pcap -nr
Running as user "root" and group "root". This could be dangerous.
 1   0.000000 192.168.10.20 -> 192.168.10.11 TCP 43408 > 80 [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSV=6038716 TSER=0 WS=6
 2   0.000082 192.168.10.11 -> 192.168.10.20 TCP 80 > 43408 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 SACK_PERM=1 TSV=1215460559 TSER=6038716 WS=7
 3   0.000703 192.168.10.20 -> 192.168.10.11 TCP 43408 > 80 [ACK] Seq=1 Ack=1 Win=14656 Len=0 TSV=6038716 TSER=1215460559
 4   0.000716 192.168.10.20 -> 192.168.10.11 HTTP GET /index.html HTTP/1.0
 5   0.000734 192.168.10.11 -> 192.168.10.20 TCP 80 > 43408 [ACK] Seq=1 Ack=122 Win=5888 Len=0 TSV=1215460560 TSER=6038716
 6   0.001400 192.168.10.11 -> 192.168.10.20 HTTP HTTP/1.1 200 OK  (text/html)
 7   0.001486 192.168.10.11 -> 192.168.10.20 TCP 80 > 43408 [FIN, ACK] Seq=273 Ack=122 Win=5888 Len=0 TSV=1215460560 TSER=6038716
 8   0.002151 192.168.10.20 -> 192.168.10.11 TCP 43408 > 80 [ACK] Seq=122 Ack=273 Win=15680 Len=0 TSV=6038717 TSER=1215460560
 9   0.002902 192.168.10.20 -> 192.168.10.11 TCP 43408 > 80 [FIN, ACK] Seq=122 Ack=274 Win=15680 Len=0 TSV=6038717 TSER=1215460560
10   0.002912 192.168.10.11 -> 192.168.10.20 TCP 80 > 43408 [ACK] Seq=274 Ack=123 Win=5888 Len=0 TSV=1215460562 TSER=6038717


open http.pcap w/ Reader class
>>> import dpkt
>>> f = open('/root/my_works/python_works/http.pcap')
>>> pcap = dpkt.pcap.Reader(f)


print out timestamp n’ data length
>>> for ts,buf in pcap:
...     print ts,len(buf)
...
1306223785.13 74
1306223785.13 74
1306223785.13 66
1306223785.13 187
1306223785.13 66
1306223785.13 338
1306223785.13 66
1306223785.13 66
1306223785.13 66
1306223785.13 66


print out pcap file w/ dpkt
>>> for ts,buf in pcap:
...     eth = dpkt.ethernet.Ethernet(buf)
...
>>>

>>> eth
Ethernet(src='\x00&U\xe1\xae\xfa', dst='RT\x00oe\xa6', data=IP(src='\xc0\xa8\n\x0b', off=16384, dst='\xc0\xa8\n\x14', sum=57591, len=52, p=6, id=50268, data=TCP(seq=3239948698L, off_x2=128, ack=3287213264L, win=46, sum=14697, flags=16, dport=43408, sport=80)))
>>>


>>> ip = eth.data  <- ip
>>> tcp = ip.data  <- tcp
>>>
>>> ip
IP(src='\xc0\xa8\n\x0b', off=16384, dst='\xc0\xa8\n\x14', sum=57591, len=52, p=6, id=50268, data=TCP(seq=3239948698L, off_x2=128, ack=3287213264L, win=46, sum=14697, flags=16, dport=43408, sport=80))
>>>
>>> tcp
TCP(seq=3239948698L, off_x2=128, ack=3287213264L, win=46, sum=14697, flags=16, dport=43408, sport=80)
>>>
>>> ip.src
'\xc0\xa8\n\x0b'
>>>
>>> tcp.seq
3239948698L
>>>


parse HTTP
>>> for ts, buf in pcap:
...     eth = dpkt.ethernet.Ethernet(buf)
...     ip = eth.data
...     tcp = ip.data
...     if tcp.dport == 80 and len(tcp.data) > 0:
...             http = dpkt.http.Request(tcp.data)
...             print http.uri
...     print ts
...
1306223785.13
1306223785.13
1306223785.13
/index.html
1306223785.13
1306223785.13
1306223785.13
1306223785.13
1306223785.13
1306223785.13
1306223785.13
>>>


get only HTTP method
>>> for ts,buf in pcap:
...     eth = dpkt.ethernet.Ethernet(buf)
...     ip = eth.data
...     tcp = ip.data
...     if tcp.dport == 80 and len(tcp.data) > 0:
...             http = dpkt.http.Request(tcp.data)
...
>>> http
Request(uri='/index.html')
>>> http.method
'GET'
>>> http.uri
'/index.html'
>>> http.version
'1.0'
>>> http.headers
{'host': '192.168.10.11', 'connection': 'Keep-Alive', 'accept': '*/*', 'user-agent': 'Wget/1.12 (linux-gnu)'}


len(tcp.data) > 0 eliminates non HTTP packets , such as syn , ack , fin ,rst.

parse HTTP packets
 

client -------------------------- Apache

         -> HTTP request ( tcp src = 43408 , dst dst = 80 )
         <- HTTP response ( tcp src = 80 , tcp dst = 43408 )

>>> for ts,buf in pcap:
...     eth = dpkt.ethernet.Ethernet(buf)
...     ip = eth.data
...     tcp = ip.data
...     if tcp.sport == 80 and len(tcp.data) > 0:
...             http = dpkt.http.Response(tcp.data)
...
>>> http
Response(version='1.1')
>>> http.version
'1.1'
>>> http.status
'200'
>>> http.reason
'OK'
>>> http.headers
{'content-length': '6', 'accept-ranges': 'bytes', 'server': 'Apache/2.2.3 (CentOS)', 'last-modified': 'Wed, 09 Mar 2011 10:25:26 GMT', 'connection': 'close', 'etag': '"1b60d31-6-49e0a25b01180"', 'date': 'Tue, 24 May 2011 07:56:25 GMT', 'content-type': 'text/html; charset=UTF-8'}
>>> http.body
'hello\n'
>>>


HTTP request n’ response parser.
# cat http_request_response_parser.py
#!/usr/bin/env python

import dpkt

f = open('/root/my_works/python_works/http.pcap')
pcap = dpkt.pcap.Reader(f)

# load HTTP pcap file n' link to dpkt attributes

for ts,buf in pcap:
       eth = dpkt.ethernet.Ethernet(buf)
       ip = eth.data
       tcp = ip.data
       if tcp.dport == 80 and len(tcp.data) > 0:
               http_req = dpkt.http.Request(tcp.data)
       if tcp.sport == 80 and len(tcp.data) > 0:
               http_res = dpkt.http.Response(tcp.data)

# HTTP request parser

print "\r\n"

print "HTTP Request\r\n"
print tcp.dport
print http_req.method
print http_req.uri
print http_req.version
print http_req.headers

print "\r\n"
print "\r\n"

# HTTP response parser

print "HTTP Response\r\n"
print tcp.sport
print http_res.status
print http_res.reason
print http_res.version
print http_res.headers
print http_res.body


f.close()
#


output
root@bt:~/my_works/python_works# ./http_request_response_parser.py


The following is HTTP Request

43408
GET
/index.html
1.0
{'host': '192.168.10.11', 'connection': 'Keep-Alive', 'accept': '*/*', 'user-agent': 'Wget/1.12 (linux-gnu)'}


The following is HTTP Response

80
200
OK
1.1
{'content-length': '6', 'accept-ranges': 'bytes', 'server': 'Apache/2.2.3 (CentOS)', 'last-modified': 'Wed, 09 Mar 2011 10:25:26 GMT', 'connection': 'close', 'etag': '"1b60d31-6-49e0a25b01180"', 'date': 'Tue, 24 May 2011 07:56:25 GMT', 'content-type': 'text/html; charset=UTF-8'}
hello

Python: python-dpkt : send an ICMP echo packet w/ python-dpkt

I am a newbie to python script.
just follow instructions.
http://jon.oberheide.org/blog/2008/08/25/dpkt-tutorial-1-icmp-echo/

Many thx XD

OS : BackTrack Linux 5 ( installed python-dpkt )

1. send an ICMP echo packet w/ python-dpkt

This tutorial is very useful for me to study python.
root@bt:~# less /usr/share/pyshared/dpkt/icmp.py


imcp.py
class ICMP(dpkt.Packet):
   __hdr__ = (
       ('type', 'B', 8),
       ('code', 'B', 0),
       ('sum', 'H', 0)
       )
   class Echo(dpkt.Packet):
       __hdr__ = (('id', 'H', 0), ('seq', 'H', 0))

>>> dir(dpkt.icmp.ICMP.Echo)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__hdr__', '__hdr_defaults__', '__hdr_fields__', '__hdr_fmt__', '__hdr_len__', '__init__', '__len__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', 'data', 'id', 'pack', 'pack_hdr', 'seq', 'unpack']


create echo payload
>>> import dpkt
>>> echo = dpkt.icmp.ICMP.Echo()

>>> print `echo`
Echo()


Echo payloads:
id : 16bit int ( ‘H’) : default 0   ('id', 'H', 0)
seq : 16bit int (‘H’) : default 0   ('seq', 'H', 0)

create id n’ seq # w/ random.randint
>>> import random
>>> random.randint(0,0xffff)
23065


create id , seq attributes
>>> import random
>>> echo.id = random.randint(0,0xffff)
>>> echo.seq = random.randint(0,0xffff)

>>> print `echo`
Echo(id=46957, seq=51509)


create data attributes
>>> echo.data = 'hello world'
>>>
>>> print `echo`
Echo(id=46957, seq=51509, data='hello world')


create ICMP payload n’ assign its attributes
>>> icmp = dpkt.icmp.ICMP()
>>> icmp.type = dpkt.icmp.ICMP_ECHO


link Echo payload to data ICMP attribute
>>> icmp.data = echo
>>>

>>> print `echo`
Echo(id=46957, seq=51509, data='hello world')

>>> print `icmp.data`
Echo(id=46957, seq=51509, data='hello world')

>>> print `icmp`
ICMP(data=Echo(id=46957, seq=51509, data='hello world'))

>>> import binascii
>>> print binascii.hexlify(str(icmp))
0800e58db76dc93568656c6c6f20776f726c64

>>> print str(icmp)
卷mノ5hello world


Next create a socket for ICMP.
>>> s = socket.socket(socket.AF_INET, socket.SOCK_RAW, dpkt.ip.IP_PROTO_ICMP)
>>> s.connect(('192.168.10.11',1))



send an ICMP echo to 192.168.10.11
>>> s.send(str(icmp))
19


Captured on 192.168.10.11
# tshark -i eth2 icmp
102.144392 192.168.10.20 -> 192.168.10.11 ICMP Echo (ping) request
102.144420 192.168.10.11 -> 192.168.10.20 ICMP Echo (ping) reply

root@bt:~/my_works# cat ping.py
#!/usr/bin/env python

import dpkt,socket,random

echo = dpkt.icmp.ICMP.Echo()
echo.id = random.randint(0, 0xffff)
echo.seq = random.randint(0, 0xffff)
echo.data = 'hello world'

icmp = dpkt.icmp.ICMP()
icmp.type = dpkt.icmp.ICMP_ECHO
icmp.data = echo

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, dpkt.ip.IP_PROTO_ICMP)
s.connect(('192.168.10.11', 1))
sent = s.send(str(icmp))

print 'sent %d bytes' % sent

root@bt:~/my_works# python ping.py
sent 19 bytes