2012-08-01 39 views
7

我想通過使用tcpdump來嗅探http頭。瞭解Tcpdump過濾器和位掩碼

該過濾器效果很好,但我不明白 -

(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) 

我GOOGLE了,但我無法找到任何有用的信息

這裏是整個tcpdump命令

sudo tcpdump -A 'dst [dest host] or src [src host] and tcp and 
(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -i eth0 

回答

15

這不是BPF過濾器,它可以獲取http頭文件,但tcpdump命令中的「-A」開關。

您的tcpdump命令查找tcp流量到某個目標或來自eth0上的某個源,其中最終的BPF過濾器涉及一個導致總數不爲零的計算。使用「-A」選項,它會以ASCII格式打印每個數據包,然後打印其鏈接級別標題。

我已經解釋了下面的計算,但我相信在實際的過濾器中可能存在一些問題,可能是通過複製和粘貼。當您使用tcpdump的這些過濾器,你使用TCP位掩碼,檢查不落在字節邊界

  • ip[2:2]指的是兩個字節(即第3 & 4字節)字段時,通常會使用在IP報頭中,從字節2開始(記住它從偏移量0開始)。該總和表示可以是最大65535字節的IP分組的總長度。

對於這裏的掩碼,爲清楚起見,我已經預先計劃一個「0」,從而掩蓋0xf變得0x0f。根據下面的GuyHarris的評論,掩碼中的前導'0'被丟棄。

  • ip[0]&0x0f指字節0的在IP報頭中的第二半(即第一字節),這將會給你在32個字,因此IP報頭長度,這通常通過4乘以這樣的計算。

  • tcp[12]&0xf0)指的是字節12的前半部分(即第11個字節),它是數據偏移字段,用32位字指定TCP頭部的大小,因此通常乘以4進行這樣的計算。

您需要通過4乘最後2米的長度,因爲他們是32位/ 4字節字等都需要被翻譯成一個總以字節爲單位的計算是正確的

你的過濾器應該是計算:

  • 該IP包的長度(以字節爲單位) - 該IP報頭長度 - TCP報頭長度

並尋找該值被澤RO,即像這樣

sudo tcpdump -A -nnpi eth0 '(ip[2:2] - ((ip[0]&0x0f)*4) - ((tcp[12]&0xf0)*4) != 0)'

當您執行減法,你正在尋找一個非零總。這個非零總數意味着存在第4層以上的數據,即tcp有效載荷中的數據,通常是應用程序流量。

您可能還需要添加port 80假設大多數HTTP流量是通過端口80

這樣的過濾器是常用的安全民俗來檢測一個SYN,這是不正常的,但根據RFC的數據,這是允許的。所以整個事情看起來是這樣的 -

'tcp[13]=0x02 and (ip[2:2] - ((ip[0]&0x0f)*4) - ((tcp[12]&0xf0)*4) != 0)'

TCPIPGuide是TCP/IP很好的,免費在線指導BTW。

更新:根據Guy Harris的更新修改位掩碼中的「前導零」部分。

+1

'0x0f'和'0xf'是相同的東西;前導零可以在十六進制值中省略。但是,如果前導零存在,代碼可能會讀取更多*清楚*。 「<< 2」與「* 4」相同;然而'2'是'/ 2'(除以2),這是錯誤的 - 這可能是一個錯字。 – 2012-08-02 17:38:59

+1

非常全面的答覆! – kingasmk 2012-08-02 23:32:07

+1

@GuyHarris thx,我不確定前導零是否被刪除,所以只是認爲我爲了清晰起見而提出了我的評論。關於''2'與'* 4'相同,爲了清楚起見,我只是簡單地將它從'>> 2'中改爲'* 4',因爲'* 4'非常清楚,並且感覺有必要解釋這些值的差異(32位字與字節),並消除圍繞「<< 2」錯字的懷疑。 – 2012-08-03 09:08:24