Scapy/Pcap Reader
From charlesreid1
Creating a pcap file reader in Scapy.
http://www.secdev.org/projects/scapy/doc/usage.html
Contents
The Summary
You will need a pcap file to begin with. (Use Tcpdump or some other utility.)
Once you've got your pcap file:
- Read in the pcap file
- Loop through each packet to gather some basic aggregate statistics
Read Pcap File
Start scapy:
$ scapy Welcome to Scapy (2.3.1) >>>
To read a pcap file, use the rdpcap()
method and pass the absolute path to the pcap file:
>>> a=rdpcap("/path/to/capture.pcap")
Now you should be able to see the number of packets:
>>> len(a) 2055
Analyzing a Packet
Start by analyzing a single packet:
>>> pkt = a[3]
Packet Methods
Getting an individual packet returns an object of type Dot11 (as in, an 802.11 wireless packet):
>>> type(pkt) <class 'scapy.layers.dot11.Dot11'>
Start by checking out what functions are available for an individual packet:
>>> dir(pkt) ['__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__div__', '__doc__', '__eq__', '__format__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__len__', '__lt__', '__metaclass__', '__module__', '__mul__', '__ne__', '__new__', '__nonzero__', '__rdiv__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__rtruediv__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__truediv__', '__weakref__', '_do_summary', 'add_payload', 'add_underlayer', 'aliastypes', 'answers', 'build', 'build_done', 'build_padding', 'build_ps', 'canvas_dump', 'clone_with', 'command', 'copy', 'decode_payload_as', 'default_fields', 'default_payload_class', 'delfieldval', 'display', 'dissect', 'dissection_done', 'do_build', 'do_build_payload', 'do_build_ps', 'do_dissect', 'do_dissect_payload', 'do_init_fields', 'explicit', 'extract_padding', 'fields', 'fields_desc', 'fieldtype', 'firstlayer', 'fragment', 'from_hexcap', 'get_field', 'getfield_and_val', 'getfieldval', 'getlayer', 'guess_payload_class', 'hashret', 'haslayer', 'hide_defaults', 'init_fields', 'initialized', 'lastlayer', 'libnet', 'lower_bonds', 'mysummary', 'name', 'original', 'overload_fields', 'overloaded_fields', 'packetfields', 'payload', 'payload_guess', 'pdfdump', 'post_build', 'post_dissect', 'post_dissection', 'post_transforms', 'pre_dissect', 'psdump', 'raw_packet_cache', 'remove_payload', 'remove_underlayer', 'route', 'self_build', 'sent_time', 'setfieldval', 'show', 'show2', 'show_indent', 'sprintf', 'summary', 'time', 'underlayer', 'unwep', 'upper_bonds'] >>>
Printing a Packet
A string dump of the packet is not very useful:
>>> str(pkt) "\x80\x00\x00\x00\xff\xff\xff\xff\xff\xff\x8c\x04\xff\xed\xa9O\x8c\x04\xff\xed\xa9O\x80a\x84\xb18\x9bX\x00\x00\x00d\x00\x11\x04\x00\tHOME-A94F\x01\x08\x82\x84\x8b\x96$\xb0Hl\x03\x01\x01\x05\x04\x00\x01\x00\x00*\x01\x00/\x01\x000\x18\x01\x00\x00\x0f\xac\x02\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x02\x01\x00\x00\x0f\xac\x02\x0c\x002\x04\x8c\x12\x98`-\x1a\xbd\x18\x1b\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x16\x01\x08\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\x18\x00P\xf2\x04\x10J\x00\x01\x10\x10D\x00\x01\x02\x10I\x00\x06\x007*\x00\x01 \xdd\t\x00\x10\x18\x02\x00\x00\x1c\x00\x00\xdd\x1c\x00P\xf2\x01\x01\x00\x00P\xf2\x02\x02\x00\x00P\xf2\x04\x00P\xf2\x02\x01\x00\x00P\xf2\x02\x0c\x00\xdd\x18\x00P\xf2\x02\x01\x01\x80\x00\x03\xa4\x00\x00'\xa4\x00\x00BC^\x00b2/\x00"
But a hex dump is starting to look a little bit better:
>>> hexdump(pkt) 0000 80 00 00 00 FF FF FF FF FF FF 8C 04 FF ED A9 4F ...............O 0010 8C 04 FF ED A9 4F 80 61 84 B1 38 9B 58 00 00 00 .....O.a..8.X... 0020 64 00 11 04 00 09 48 4F 4D 45 2D 41 39 34 46 01 d.....HOME-A94F. 0030 08 82 84 8B 96 24 B0 48 6C 03 01 01 05 04 00 01 .....$.Hl....... 0040 00 00 2A 01 00 2F 01 00 30 18 01 00 00 0F AC 02 ..*../..0....... 0050 02 00 00 0F AC 04 00 0F AC 02 01 00 00 0F AC 02 ................ 0060 0C 00 32 04 8C 12 98 60 2D 1A BD 18 1B FF FF FF ..2....`-....... 0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0080 00 00 00 00 3D 16 01 08 11 00 00 00 00 00 00 00 ....=........... 0090 00 00 00 00 00 00 00 00 00 00 00 00 DD 18 00 50 ...............P 00a0 F2 04 10 4A 00 01 10 10 44 00 01 02 10 49 00 06 ...J....D....I.. 00b0 00 37 2A 00 01 20 DD 09 00 10 18 02 00 00 1C 00 .7*.. .......... 00c0 00 DD 1C 00 50 F2 01 01 00 00 50 F2 02 02 00 00 ....P.....P..... 00d0 50 F2 04 00 50 F2 02 01 00 00 50 F2 02 0C 00 DD P...P.....P..... 00e0 18 00 50 F2 02 01 01 80 00 03 A4 00 00 27 A4 00 ..P..........'.. 00f0 00 42 43 5E 00 62 32 2F 00 .BC^.b2/.
Each of these pieces of data represents a different part of the packet header, which includes information about the source, destination, timestamp, channel, and so on. Use the show method for an individual packet to show the full description:
>>> pkt.show() ###[ 802.11 ]### subtype= 8L type= Management proto= 0L FCfield= ID= 0 addr1= ff:ff:ff:ff:ff:ff addr2= 3c:34:ff:43:a3:4d addr3= 3c:34:ff:43:a3:4d SC= 24960 addr4= None ###[ 802.11 Beacon ]### timestamp= 380561305988 beacon_interval= 100 cap= short-slot+ESS+privacy ###[ 802.11 Information Element ]### ID= SSID len= 9 info= 'HOME-A94F' ###[ 802.11 Information Element ]### ID= Rates len= 8 info= '\x82\x84\x8b\x96$\xb0Hl' ###[ 802.11 Information Element ]### ID= DSset len= 1 info= '\x01' ###[ 802.11 Information Element ]### ID= TIM len= 4 info= '\x00\x01\x00\x00' ###[ 802.11 Information Element ]### ID= ERPinfo len= 1 info= '\x00' ###[ 802.11 Information Element ]### ID= ERPinfo len= 1 info= '\x00' ###[ 802.11 Information Element ]### ID= RSNinfo len= 24 info= '\x01\x00\x00\x0f\xac\x02\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x02\x01\x00\x00\x0f\xac\x02\x0c\x00' ###[ 802.11 Information Element ]### ID= ESRates len= 4 info= '\x8c\x12\x98`' ###[ 802.11 Information Element ]### ID= 45 len= 26 info= '\xbd\x18\x1b\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ###[ 802.11 Information Element ]### ID= 61 len= 22 info= '\x01\x08\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ###[ 802.11 Information Element ]### ID= vendor len= 24 info= '\x00P\xf2\x04\x10J\x00\x01\x10\x10D\x00\x01\x02\x10I\x00\x06\x007*\x00\x01 ' ###[ 802.11 Information Element ]### ID= vendor len= 9 info= '\x00\x10\x18\x02\x00\x00\x1c\x00\x00' ###[ 802.11 Information Element ]### ID= vendor len= 28 info= '\x00P\xf2\x01\x01\x00\x00P\xf2\x02\x02\x00\x00P\xf2\x04\x00P\xf2\x02\x01\x00\x00P\xf2\x02\x0c\x00' ###[ 802.11 Information Element ]### ID= vendor len= 24 info= "\x00P\xf2\x02\x01\x01\x80\x00\x03\xa4\x00\x00'\xa4\x00\x00BC^\x00b2/\x00"
Finding Packets by Type
To get most of the information about a packet, you can use the fields attribute, which is a dictionary containing key-value pairs. One of these is "subtype" - which corresponds to the Frame Type/Subtype table here:
http://www.willhackforsushi.com/papers/80211_Pocket_Reference_Guide.pdf
If you loop over each packet and print out its subtype, you'll see all the values are the values found in the table.
from scapy.all import * a = rdpcap("awesome-02.cap") #for i in range(len(a)): for i in range(100): t = a[i].fields['subtype'] print t
Checking the pocket reference, we can filter out and look at certain types of packets. For example, searching for beacon packets is a quick way to find access points in the nearby area.
scapy a Python library for interfacing with network devices and analyzing packets from Python.
Building Wireless Utilities: Scapy/Airodump Clone · Scapy/AP Scanner Analyzing Conversations: Scapy/Conversations Database: Scapy/Wifi Database Category:Scapy · Category:Python · Category:Networking
|