我正在尝试从pcap文件中的每个数据包中提取特定字节。所有数据包都是ICMP。
在数据部分中,有一个字节会更改每个数据包。每个位置都相同。我想提取那个字节。
使用船头:
pkts = rdpcap('test.pcap')
pl = PacketList([p for p in pkts])
bytes(pl[12].payload)
返回以下内容:
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'
我将要提取的字节括在三颗星内。但是,如果我打印出每个数据包的字节,则我要提取的字节将处于不同的偏移量。
如果我按如下方式为每个数据包运行一个十六进制转储:
hexdump(bytes(pl[12].payload))
我要提取的特定字节始终处于相同位置,但我不知道如何提取它。
如何使用Scapy从pcap中提取特定字节?
在此之后跟随此答案:Get specific bytes in payload from a pcap file
如果我执行相同的命令,它不会做任何有用的事情:
>>> hexdump(pkts[14][2].load[8])
0000 00 00 00 00 00 00 00 00 ........
>>>
您想要TTL吗?
让我们从高处开始,然后向下移动。
Scapy正在为您提供构造好的数据包。如果需要数据包的TTL,请调用属性:
>>> plist[182].ttl
64
如果要获取数据包的特定字节,请看一下十六进制转储:
>>> 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]....(..
...
这些以十六进制表示,第一个字段0000是偏移量,然后是16字节以十六进制表示,然后是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.
东西从0开始,因此第一行的字节地址为0..15。第二行偏移量是16(16 * 1)。因此字节地址为16..31。第三行,偏移量是32(16 * 2)。所以字节地址是32..47
您突出显示了第2行的第7个字节:
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]....(..
那个地址是:
offset + byte_address.
offset = 16 * 1
byte_address = 6
哪个给我们:
16 + 6 = 22
这样,我们现在可以从原始数据包中获取字节地址22:
>>> b = raw(plist[182])
>>> b[22]
64
请注意,wireshark数据包编号从1开始。python中的数据包将从0开始。因此,在我的示例中,数据包182对应于Wireshark中的数据包183。
plist [182] .payload为您提供了数据包的IP部分,因此偏移量将有所不同,因为我们不再关注整个数据包了。我们可以使用'.ttl'属性获得相同的值。或者,知道地址是IP标头中的字节8:
>>> plist[182].payload.ttl
64
>>> raw(plist[182].payload)[8]
64