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

jui*_*0xk 3 python scapy wireshark

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

在数据部分,有一个字节会改变每个数据包。每个人都处于相同的位置。我想提取那个字节。

在此处输入图片说明

使用 scapy:

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

bytes(pl[12].payload)
Run Code Online (Sandbox Code Playgroud)

返回以下内容:

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))
Run Code Online (Sandbox Code Playgroud)

我要提取的特定字节总是在相同的位置,但我不知道如何提取它。

如何使用 scapy 从 pcap 中提取特定字节?

按照这里的答案:从 pcap 文件中获取有效负载中的特定字节

如果我执行相同的命令,它不会做任何有用的事情:

>>> hexdump(pkts[14][2].load[8])
0000  00 00 00 00 00 00 00 00                          ........
>>>
Run Code Online (Sandbox Code Playgroud)

Ste*_*ham 5

你想要TTL吗?

让我们从高层开始,然后向下移动。

Scapy 正在为您提供构建的数据包。如果你想要数据包的 TTL,调用属性:

>>> plist[182].ttl
64
Run Code Online (Sandbox Code Playgroud)

如果要获取数据包的特定字节,请查看 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.@.@.d....(..
...
Run Code Online (Sandbox Code Playgroud)

这些是十六进制的,第一个字段 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.
Run Code Online (Sandbox Code Playgroud)

事情从 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.@.@.d....(..
Run Code Online (Sandbox Code Playgroud)

该地址是:

offset + byte_address.
offset = 16 * 1
byte_address = 6
Run Code Online (Sandbox Code Playgroud)

这给了我们:

16 + 6 = 22
Run Code Online (Sandbox Code Playgroud)

有了这个,我们现在可以从原始数据包中获取字节地址 22:

>>> b = raw(plist[182])
>>> b[22]
64
Run Code Online (Sandbox Code Playgroud)

请注意,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
Run Code Online (Sandbox Code Playgroud)