Python3 Scapy嗅探碎片化IP数据包

2024-04-19 23:17:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过以下设置简化我的问题

  • 我的本地接口(192.168.183.130)上端口1337上的一个简单netcat UDP侦听器
  • 一个简单的netcat UDP客户端连接到端口1337上的侦听器(来自192.168.183.128)
  • 一个运行在192.168.183.130上的非常基本的scapy嗅探器

以root权限运行的Scapy嗅探器:

from scapy.all import sniff, IP, UDP

def print_package(packet):
    packet.show()


sniff(filter="ip dst host 192.168.183.130 and dst port 1337", iface="ens33", prn=print_package)

发送具有1500字节MTU限制的IP数据包/UDP帧就像一个符咒,数据包按预期打印到std输出。一旦我成功通过限制,IP协议就会创建片段,嗅探器只捕获第一个数据包(正确的标志、len等)

在下面的示例中,在使用netcat发送3200*“a”之前,我从nc客户端向侦听器发送了一个简单字符串“next message will is 3200*“a”。数据包被分割成三个IP数据包,并由堆栈正确地重新组装,然后由netcat使用的UDP套接字接收数据包,因此一切都按照我所期望的网络方式工作。Scapy只嗅探三个数据包中的第一个,我不明白为什么会发生这种情况

屏幕截图显示了对文本消息和wireshark中三个IP片段的预期/正确处理:

Expected behavior in wireshark

以下代码段显示了到标准输出的scapy输出:

sudo python3 scapy_test.py 
    
    ###[ Ethernet ]### 
      dst       = 00:0c:29:fa:93:72
      src       = 00:0c:29:15:2a:11
      type      = IPv4
    ###[ IP ]### 
         version   = 4
         ihl       = 5
         tos       = 0x0
         len       = 59
         id        = 18075
         flags     = DF
         frag      = 0
         ttl       = 64
         proto     = udp
         chksum    = 0x3c3
         src       = 192.168.183.128
         dst       = 192.168.183.130
         \options   \
    ###[ UDP ]### 
            sport     = 59833
            dport     = 1337
            len       = 39
            chksum    = 0xdaa0
    ###[ Raw ]### 
               load      = 'next message will be 3200 * "A"\n'
    
    ###[ Ethernet ]### 
      dst       = 00:0c:29:fa:93:72
      src       = 00:0c:29:15:2a:11
      type      = IPv4
    ###[ IP ]### 
         version   = 4
         ihl       = 5
         tos       = 0x0
         len       = 1500
         id        = 20389
         flags     = MF
         frag      = 0
         ttl       = 64
         proto     = udp
         chksum    = 0x1518
         src       = 192.168.183.128
         dst       = 192.168.183.130
         \options   \
    ###[ UDP ]### 
            sport     = 59833
            dport     = 1337
            len       = 3209
            chksum    = 0x25bd
    ###[ Raw ]### 
               load      = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'

为什么其他IP片段丢失,我如何嗅探它们? 我知道sniff中的session参数,但实际上我没有用session=IPSession重新组装数据包。(无论如何,这不是我想要实现的,对于我的应用程序,我想要嗅探所有片段,更改它们的一部分,并将它们转发到另一个地址/套接字。)


Tags: 端口ipsrc客户端len数据包scapydst
1条回答
网友
1楼 · 发布于 2024-04-19 23:17:00

我终于自己弄明白了,所以我要留下一个答案:

问题在于嗅探器的过滤器:

sniff(filter="ip dst host 192.168.183.130 and dst port 1337", iface="ens33", prn=print_package)

第一个之后的IP片段没有UDP部分,因此没有目标端口,因此scapy筛选器无法捕获它们。为了解决这个问题,我扩展了过滤器以捕获dst端口1337或带有偏移量的片段。我偶然发现了这个备忘单https://github.com/SergK/cheatsheat-tcpdump/blob/master/tcpdump_advanced_filters.txt,它为这个问题提供了一个有效的berkeley语法,并最终得到了这个过滤器(用于简化的问题)

sniff(filter="ip dst host 192.168.183.130 and ((src port 1337) or (((ip[6:2] > 0) or (ip[7] > 0)) and (not ip[6] = 64))", iface="ens33", prn=print_package)

这将检查数据包的片段偏移量是否为>;0(第六个字节的前三位(标志)或第七个字节之后的任何内容均为>;0),并且如果未设置“不分段”位。如果这是真的,它是一个IP片段,嗅探器将嗅探它

相关问题 更多 >