From charlesreid1

Creating a pcap file reader in Scapy.

http://www.secdev.org/projects/scapy/doc/usage.html

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.