使用Scapy从pcap文件中提取负载中的特定字节

3

我正尝试从pcap文件的每个数据包中提取特定的字节。所有数据包均为ICMP。

在数据部分,有一个字节会随着每个数据包而改变。它在每个数据包中都是相同的位置。我想要提取那个字节。

enter image description here

使用Scapy:

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:

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                          ........
>>>
1个回答

9

您需要 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.@.@.d....(..
...

这些是十六进制表示的,第一个字段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。

您在第二行突出显示了第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.@.@.d....(..

那个地址是:
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接