tcpdump的基本用法之過濾表示式
上篇部落格寫了tcpdump選項的用法, 這篇部落格我們來看一下過濾表示式。
過濾表示式的man手冊:man pcap-filter
tcpdump在使用過濾表示式時,如有用了shell的萬用字元,需要用單引號引起來。
情形1:只抓udp的包
#tcpdump -i eth0 -c 10 'udp'
情形2:只想檢視源機器和目的機器的包
# tcpdump -i eth0 'dst 8.8.8.8'
tcpdump還支援使用and和or來進行搭配
如果沒有設定,預設是src or dst,就是源機器是8.8.8.8或者目的機器是8.8.8.8都行。
情形3:只想檢視目標機器埠是53或80的包
# tcpdump -i eth0 -c 3 'dst port 53 or dst port 80'
我們可以設定過濾型別,上面例子中我們使用了port這個型別,就是來指定埠。當然,tcpdump還支援如下的型別:
1 host:指定主機名或IP地址,例如’host roclinux.cn’或’host 202.112.18.34′
2 net :指定網路段,例如’arp net 128.3’或’dst net 128.3′
3 portrange:指定埠區域,例如’src or dst portrange 6000-6008′
如果我們沒有設定過濾型別,那麼預設是host。
情形4:我想抓到那些通過eth0網絡卡的,且來源是roclinux.cn伺服器或者目標是roclinux.cn伺服器的網路包
tcpdump -i eth0 'host roclinux.cn'
情形5:我想抓通過eth0網絡卡的,且roclinux.cn和baidu.com之間通訊的網路包,或者,roclinux.cn和qiyi.com之間通訊的網路包
tcpdump -i eth0 'host roclinux.cn and (baidu.com or qiyi.com)'
情形6:我想獲取使用ftp埠和ftp資料埠的網路包
tcpdump 'port ftp or ftp-data'
情形7:我想獲取roclinux.cn和baidu.com之間建立TCP三次握手中第一個網路包,即帶有SYN標記位的網路包,另外,目的主機不能是qiyi.com
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and not dst host qiyi.com'
情形8:列印IP包長超過576位元組的網路包
tcpdump 'ip[2:2] > 576'
情形9:列印廣播包或多播包,同時資料鏈路層不是通過乙太網媒介進行的
tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
proto [ expr : size],只要掌握了這個語法格式,相信大家就能看懂上面的三個稀奇古怪的表示式了。
proto就是protocol的縮寫,表示這裡要指定的是某種協議的名稱,比如ip、tcp、ether。其實proto這個位置,總共可以指定的協議型別有15個之多,包括:
- ether – 鏈路層協議
- fddi – 鏈路層協議
- tr – 鏈路層協議
- wlan – 鏈路層協議
- ppp – 鏈路層協議
- slip – 鏈路層協議
- link – 鏈路層協議
- ip
- arp
- rarp
- tcp
- udp
- icmp
- ip6
- radio
- expr
用來指定資料報偏移量,表示從某個協議的資料報的第多少位開始提取內容,預設的起始位置是0;而size表示從偏移量的位置開始提取多少個位元組,可以設定為1、2、4。
如果只設置了expr,而沒有設定size,則預設提取1個位元組。比如ip[2:2],就表示提取出第3、4個位元組;而ip[0]則表示提取ip協議頭的第一個位元組。
在我們提取了特定內容之後,我們就需要設定我們的過濾條件了,我們可用的“比較操作符”包括:>,<,>=,<=,=,!=,總共有6個。
好,掌握了上面內容之後,我可以很負責任的告訴你,你已經掌握了tcpdump過濾表示式的最重要語法了。我們先來小試牛刀,看一個例題:
ip[0] & 0xf != 5
IP協議的第0-4位,表示IP版本號,可以是IPv4(值為0100)或者IPv6(0110);第5-8位表示首部長度,單位是“4位元組”,如果首部長度為預設的20位元組的話,此值應為5, 即”0101″。ip[0]則是取這兩個域的合體。0xf中的0x表示十六進位制,f是十六進位制數,轉換成8位的二進位制數是“0000 1111”。而5是一個十進位制數,它轉換成8位二進位制數為”0000 0101″。
有了上面這些分析,大家應該可以很清楚的知道,這個語句中!=的左側部分就是提取IP包首部長度域,如果首部長度不等於5,就滿足過濾條件。言下之意也就是說,要求IP包的首部中含有可選欄位。
大家可能已經有所體會,在寫過濾表示式時,你需要把協議格式完全背在腦子裡,才能把表示式寫對。可這對大多數人來說,可能有些困難。為了讓tcpdump工具更人性化一些,有一些常用的偏移量,可以通過一些名稱來代替,比如icmptype表示ICMP協議的型別域、icmpcode表示ICMP的code域,tcpflags則表示TCP協議的標誌欄位域。
更進一步的,對於ICMP的型別域,可以用這些名稱具體指代:icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply。
而對於TCP協議的標誌欄位域,則可以細分為tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg。
如果一個過濾表示式有多個過濾條件,那麼就需要使用邏輯符了,其中,!或not都可以表示“否定”,&&與and都可以表示“與”,而||與or都可以表示“或”
update:
抓取http包:
tcpdump -Xvvenn -i eth1 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 -w tcpdump.cap
0x4745 為"GET"前兩個字母"GE"。
0x4854 為"HTTP"前兩個字母"HT"。
tcp[20:2]表示tcp頭部從第20位元組開始提取兩個位元組。由於tcp頭部一共20個位元組,所以接下來的2個位元組就是資料的前兩個位元組。
我們抓取“GET”和"HTTP“即可。數值是它們ASCII碼的值。