簡體   English   中英

Python3 Scapy - 嗅探碎片 IP 數據包

[英]Python3 Scapy - Sniff fragmented IP packets

我試圖通過以下設置簡化我的問題。

  • 一個簡單的 netcat UDP 偵聽器,位於我的本地接口 (192.168.183.130) 上的端口 1337
  • 一個簡單的 netcat UDP 客戶端連接到端口 1337 上的偵聽器(來自 192.168.183.128)
  • 在 192.168.183.130 上運行的一個非常基本的 scapy 嗅探器

Scapy 嗅探器以 root 權限運行:

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 幀就像一個魅力,並且數據包按預期打印到標准輸出。 一旦我成功了限制並且 IP 協議創建了片段,嗅探器只會捕獲第一個數據包(正確的標志,len 等)

在以下示例中,我在使用 netcat 發送 3200 *“A”之前從 nc 客戶端向偵聽器發送了一個簡單的字符串“下一條消息將是 3200 *“A””。 在 UDP 套接字 netcat 使用接收它之前,該數據包被分成三個 IP 數據包並由堆棧正確重組,因此一切都按我所期望的網絡方式工作。 Scapy 只嗅探三個數據包中的第一個,我不明白為什么會發生這種情況。

屏幕截圖顯示了文本消息的預期/正確處理以及 wireshark 中的三個 IP 片段:

Wireshark 中的預期行為

以下片段顯示了標准輸出的 Scapy output:

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重新組裝數據包。 (無論如何,這不是我想要實現的,對於我的應用程序,我想嗅探所有片段,更改其中的一部分並將它們轉發到另一個地址/套接字。)

我終於自己弄清楚了,所以我要留下一個答案:

問題出在嗅探器的過濾器上:

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 ,它為這個問題提供了一個有效的伯克利語法並最終得到了這個過濾器(對於簡化的問題)。

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 片段,嗅探器應該嗅探它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM