Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract specific bytes in payload from a pcap file using scapy

I am trying to extract a specific byte from each packet in a pcap file. All packets are ICMP.

In the data section, there is a byte that changes each packet. It is in the same position for each one. I would like to extract that byte.

enter image description here

Using scapy:

pkts = rdpcap('test.pcap')
pl = PacketList([p for p in pkts])

bytes(pl[12].payload)

returns the following:

b'E\x00\x00T]\xa7\x00\x00***J***\x01!A\xc0\xa88\x01\xc0\xa88o\x08\x004\xe9\xbf2\x00\x00^"\x87\xbe\x00\x0c2\xf4\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 have enclosed the byte that I want to extract within three stars. However, if I print out the bytes for each packet, the byte that I want to extract will be in a different offset.

If I run a hexdump for each packet as follows:

hexdump(bytes(pl[12].payload))

The specific byte I want to extract is always in the same position, but I don't know how to extract it.

How can I extract a specific byte from a pcap using scapy?

Following this answer here: Get specific bytes in payload from a pcap file

If I execute the same command, it doesn't do anything useful:

>>> hexdump(pkts[14][2].load[8])
0000  00 00 00 00 00 00 00 00                          ........
>>>
like image 420
juiceb0xk Avatar asked Jan 25 '26 13:01

juiceb0xk


1 Answers

You want the TTL?

Lets start at the high level, and move down.

Scapy is giving you the constructed packet. If you want the TTL of the packet, call the attribute:

>>> plist[182].ttl
64

If you want to get the specific byte of the packet, lets look at the hexdump:

>>> hexdump(plist[182])
0000  AA BB CC 66 42 DE AA BB CC 3F 52 A3 08 00 45 00  .a.lM..M.AK...E.
0010  00 5B 58 B9 40 00 40 06 64 96 C0 A8 01 28 AC D9  .[X.@[email protected]....(..
...

These are in hex, the first field 0000 is the offset, then 16 bytes in hex, then ascii.

Offset  Bytes                                            ASCII
======  ===============================================  ================
0000    AA BB CC 66 42 DE AA BB CC 3F 52 A3 08 00 45 00  .a.lM..M.AK...E.

Things start at 0, so the the byte addresses are 0..15 for the first line. The second line the offset is 16 (16 * 1). So the byte addresses are 16..31. The third line, the offset is 32 (16 * 2). So the byte addresses are 32..47

You highlighted the 7th byte on row 2:

Offset Bytes                                            ASCII
       0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
====== ===============================================  ================
0010   00 5B 58 B9 40 00 40 06 64 96 C0 A8 01 28 AC D9  .[X.@[email protected]....(..

That address is:

offset + byte_address.
offset = 16 * 1
byte_address = 6

Which gives us:

16 + 6 = 22

With that, we can now get byte address 22 out of the raw packet:

>>> b = raw(plist[182])
>>> b[22]
64

Note that wireshark packet numbers start at 1. The packets in python are going to start at 0. So in my example, packet 182 corresponded to packet 183 in Wireshark.

plist[182].payload gives you the IP portion of the packet, so the offsets are going to be different since we aren't looking at the whole packet anymore. We can get the same value using the '.ttl' attribute. Or, knowing that the address is byte 8 in the IP header:

>>> plist[182].payload.ttl
64
>>> raw(plist[182].payload)[8]
64
like image 200
Steven Graham Avatar answered Jan 29 '26 00:01

Steven Graham