1、簡述html
TcpDump能夠將網絡中傳送的數據包徹底截獲下來提供分析。它支持針對網絡層、協議、主機、網絡或端口的過濾,並提供and、or、not等邏輯語句來幫助你去掉無用的信息。linux
tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ] [ -w file ] [ expression ] 抓包選項: -c:指定要抓取的包數量。注意,是最終要獲取這麼多個包。例如,指定"-c 10"將獲取10個包,但可能已經處理了100個包,只不過只有10個包是知足條件的包。 -i interface:指定tcpdump須要監聽的接口。若未指定該選項,將從系統接口列表中搜尋編號最小的已配置好的接口(不包括loopback接口,要抓取loopback接口使用tcpdump -i lo), :一旦找到第一個符合條件的接口,搜尋立刻結束。可使用'any'關鍵字表示全部網絡接口。 -n:對地址以數字方式顯式,不然顯式爲主機名,也就是說-n選項不作主機名解析。 -nn:除了-n的做用外,還把端口顯示爲數值,不然顯示端口服務名。 -N:不打印出host的域名部分。例如tcpdump將會打印'nic'而不是'nic.ddn.mil'。 -P:指定要抓取的包是流入仍是流出的包。能夠給定的值爲"in"、"out"和"inout",默認爲"inout"。 -s len:設置tcpdump的數據包抓取長度爲len,若是不設置默認將會是65535字節。對於要抓取的數據包較大時,長度設置不夠可能會產生包截斷,若出現包截斷, :輸出行中會出現"[|proto]"的標誌(proto實際會顯示爲協議名)。可是抓取len越長,包的處理時間越長,而且會減小tcpdump可緩存的數據包的數量, :從而會致使數據包的丟失,因此在能抓取咱們想要的包的前提下,抓取長度越小越好。 輸出選項: -e:輸出的每行中都將包括數據鏈路層頭部信息,例如源MAC和目標MAC。 -q:快速打印輸出。即打印不多的協議相關信息,從而輸出行都比較簡短。 -X:輸出包的頭部數據,會以16進制和ASCII兩種方式同時輸出。 -XX:輸出包的頭部數據,會以16進制和ASCII兩種方式同時輸出,更詳細。 -v:當分析和打印的時候,產生詳細的輸出。 -vv:產生比-v更詳細的輸出。 -vvv:產生比-vv更詳細的輸出。 其餘功能性選項: -D:列出可用於抓包的接口。將會列出接口的數值編號和接口名,它們均可以用於"-i"後。 -F:從文件中讀取抓包的表達式。若使用該選項,則命令行中給定的其餘表達式都將失效。 -w:將抓包數據輸出到文件中而不是標準輸出。能夠同時配合"-G time"選項使得輸出文件每time秒就自動切換到另外一個文件。可經過"-r"選項載入這些文件以進行分析和打印。 -r:從給定的數據包文件中讀取數據。使用"-"表示從標準輸入中讀取。
經常使用選項有如下幾個:web
a.tcpdump -D b.tcpdump -c num -i int -nn -XX -vvv
二、tcpdump 幾種關鍵字說明算法
第一種是關於類型的關鍵字,主要包括host,net,port, 例如 host 210.27.48.2,指明 210.27.48.2是一臺主機,net 202.0.0.0 指明 202.0.0.0是一個網絡地址,port 23 指明端口號是23。若是沒有指定類型,缺省的類型是host.
第二種是肯定傳輸方向的關鍵字,主要包括src , dst ,dst or src, dst and src ,這些關鍵字指明瞭傳輸的方向。舉例說明,src 210.27.48.2 ,指明ip包中源地址是210.27.48.2 , dst net 202.0.0.0 指明目的網絡地址是202.0.0.0 。若是沒有指明方向關鍵字,則缺省是src or dst關鍵字。shell
若是咱們只須要列出送到80端口的數據包,用dst port;若是咱們只但願看到返回80端口的數據包,用src port。 #tcpdump –i eth0 host hostname and dst port 80 目的端口是80 或者 #tcpdump –i eth0 host hostname and src port 80 源端口是80 通常是提供http的服務的主機 若是條件不少的話 要在條件以前加and 或 or 或 not #tcpdump -i eth0 host ! 211.161.223.70 and ! 211.161.223.71 and dst port 80 若是在ethernet 使用混雜模式 系統的日誌將會記錄 May 7 20:03:46 localhost kernel: eth0: Promiscuous mode enabled. May 7 20:03:46 localhost kernel: device eth0 entered promiscuous mode May 7 20:03:57 localhost kernel: device eth0 left promiscuous mode tcpdump對截獲的數據並無進行完全解碼,數據包內的大部份內容是使用十六進制的形式直接打印輸出的。顯然這不利於分析網絡故障,一般的解決辦法是先使用帶-w參數的tcpdump 截獲數據並保存到文件中,而後再使用其餘程序進行解碼分析。固然也應該定義過濾規則,以免捕獲的數據包填滿整個硬盤。
第三種是協議的關鍵字,主要包括fddi,ip,arp,rarp,tcp,udp等類型。Fddi指明是在FDDI(分佈式光纖數據接口網絡)上的特定 的網絡協議,實際上它是"ether"的別名,fddi和ether具備相似的源地址和目的地址,因此能夠將fddi協議包看成ether的包進行處理和 分析。其餘的幾個關鍵字就是指明瞭監聽的包的協議內容。若是沒有指定任何協議,則tcpdump將會監聽全部協議的信息包。
除了這三種類型的關鍵字以外,其餘重要的關鍵字以下:gateway, broadcast,less,greater,還有三種邏輯運算,取非運算是 'not ' '! ', 與運算是'and','&&;或運算 是'or' ,'||';這些關鍵字能夠組合起來構成強大的組合條件來知足人們的須要,下面舉幾個例子來講明。express
三、tcpdump 表達式vim
表達式用於篩選輸出哪些類型的數據包,若是沒有給定表達式,全部的數據包都將輸出,不然只輸出表達式爲true的包。在表達式中出現的shell元字符建議使用單引號包圍。
tcpdump的表達式由一個或多個"單元"組成,每一個單元通常包含ID的修飾符和一個ID(數字或名稱)。有三種修飾符:
(1).type:指定ID的類型。
能夠給定的值有host/net/port/portrange。例如"host foo","net 128.3","port 20","portrange 6000-6008"。默認的type爲host。
(2).dir:指定ID的方向。
能夠給定的值包括src/dst/src or dst/src and dst,默認爲src or dst。例如,"src foo"表示源主機爲foo的數據包,"dst net 128.3"表示目標網絡爲128.3的數據包,"src or dst port 22"表示源或目的端口爲22的數據包。
(3).proto:經過給定協議限定匹配的數據包類型。
經常使用的協議有tcp/udp/arp/ip/ether/icmp等,若未給定協議類型,則匹配全部可能的類型。例如"tcp port 21","udp portrange 7000-7009"。
因此,一個基本的表達式單元格式爲"proto dir type ID"windows
除了使用修飾符和ID組成的表達式單元,還有上述2小節中提到的關鍵字表達式單元:gateway,broadcast,less,greater以及算術表達式。
表達式單元之間可使用操做符" and / && / or / || / not / ! "進行鏈接,從而組成複雜的條件表達式。如"host foo and not port ftp and not port ftp-data",這表示篩選的數據包要知足"主機爲foo且端口不是ftp(端口21)和ftp-data(端口20)的包",經常使用端口和名字的對應關係可在linux系統中的/etc/service文件中找到。
另外,一樣的修飾符可省略,如"tcp dst port ftp or ftp-data or domain"與"tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain"意義相同,都表示包的協議爲tcp且目的端口爲ftp或ftp-data或domain(端口53)。
使用括號"()"能夠改變表達式的優先級,但須要注意的是括號會被shell解釋,因此應該使用反斜線"\"轉義爲"\(\)",在須要的時候,還須要包圍在引號中。緩存
2、tcpdump 具體使用方法安全
一、普通狀況下,直接啓動tcpdump將監視第一個網絡界面上全部流過的數據包。
經常使用使用方法有:
A想要截獲全部210.27.48.1 的主機收到的和發出的全部的數據包: #tcpdump host 210.27.48.1 B想要截獲主機210.27.48.1 和主機210.27.48.2 或210.27.48.3的通訊,使用命令:(在命令行中適用 括號時,必定要 #tcpdump host 210.27.48.1 and / (210.27.48.2 or 210.27.48.3 /) C若是想要獲取主機210.27.48.1除了和主機210.27.48.2以外全部主機通訊的ip包,使用命令: #tcpdump ip host 210.27.48.1 and ! 210.27.48.2 D若是想要獲取主機210.27.48.1接收或發出的telnet包,使用以下命令: #tcpdump tcp port 23 host 210.27.48.1 E 對本機的udp 123 端口進行監視 123 爲ntp的服務端口 # tcpdump udp port 123 F 系統將只對名爲hostname的主機的通訊數據包進行監視。主機名能夠是本地主機,也能夠是網絡上的任何一臺計算機。下面的命令能夠讀取主機hostname發送的全部數據: #tcpdump -i eth0 src host hostname G 下面的命令能夠監視全部送到主機hostname的數據包: #tcpdump -i eth0 dst host hostname H 咱們還能夠監視經過指定網關的數據包: #tcpdump -i eth0 gateway Gatewayname I 若是你還想監視編址到指定端口的TCP或UDP數據包,那麼執行如下命令: #tcpdump -i eth0 host hostname and port 80 J 若是想要獲取主機210.27.48.1除了和主機210.27.48.2以外全部主機通訊的ip包 ,使用命令: #tcpdump ip host 210.27.48.1 and ! 210.27.48.2 K 想要截獲主機210.27.48.1 和主機210.27.48.2 或210.27.48.3的通訊,使用命令 :(在命令行中適用 括號時,必定要 #tcpdump host 210.27.48.1 and / (210.27.48.2 or 210.27.48.3 /) L 若是想要獲取主機210.27.48.1除了和主機210.27.48.2以外全部主機通訊的ip包,使用命令: #tcpdump ip host 210.27.48.1 and ! 210.27.48.2 M 若是想要獲取主機210.27.48.1接收或發出的telnet包,使用以下命令: #tcpdump tcp port 23 host 210.27.48.1
3、tcpdump 實踐經驗
一、查看DNS解析狀況
Linux系統要想正常訪問互聯網,須要正確配置DNS解析,如今咱們已經配置公司內部DNS,咱們想看一下DNS解析是否正常,就可使用tcpdump來抓取DNS包,準備好兩個xshell
窗口,按照以下方式操做:
1.一、命令:tcpdump -n -i any port 53
儘可能在root用戶下使用tcpdump命令,-n表示不要把IP地址解析成域名,-i表示抓取哪塊網卡的通訊數據包,any表示任意一塊,port是指定要抓取數據包的端口,DNS服務工做在53端口上,執行完畢以後,咱們切換到第2個窗口,進行下一步;
1.二、命令:ping -c10 baidu.com
註解:-c10表示和ping次停下,這時候咱們的計算機和百度產生的通訊,窗口1的tcpdump就會監聽到咱們的通訊數據,也就是所謂的抓包,切換到窗口1,看到的數據大體以下:
在上圖中咱們可看到本地172.16.50.96,端口52892進程向公司本地DNS服務器 172.16.51.151請求告知baidu.com的IP地址是什麼?DNS服務器成功給了咱們答覆,由此能夠說明,咱們的DNS工做
正常。
二、抓取主機指定網卡的數據包
2.一、命令:tcpdump -i eth0 -c 10 -w data.pcap
說明:-i 指定要抓取數據包的網卡名稱
-c 指定抓取包的個數;
-w 保存到指定文件
注意:能夠看到,咱們保存的my-packets.pcap是一種特殊文件,直接使用vim是沒法查看的,能夠把
該文件拿到windows下,使用wireshark查看;
首先了解如何從包頭過濾信息
proto[x:y] : 過濾從x字節開始的y字節數。好比ip[2:2]過濾出三、4字節(第一字節從0開始排) proto[x:y] & z = 0 : proto[x:y]和z的與操做爲0 proto[x:y] & z !=0 : proto[x:y]和z的與操做不爲0 proto[x:y] & z = z : proto[x:y]和z的與操做爲z proto[x:y] = z : proto[x:y]等於z
操做符 : >, <, >=, <=, =, !=
一、IP頭(IPV4)
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | <-- optional +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DATA ... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
中文:
/*IP頭定義,共20個字節*/ typedef struct _IP_HEADER { char m_cVersionAndHeaderLen; //版本信息(前4位),頭長度(後4位) char m_cTypeOfService; // 服務類型8位 short m_sTotalLenOfPacket; //數據包長度 short m_sPacketID; //數據包標識 short m_sSliceinfo; //分片使用 char m_cTTL; //存活時間 char m_cTypeOfProtocol; //協議類型 short m_sCheckSum; //校驗和 unsigned int m_uiSourIp; //源ip unsigned int m_uiDestIp; //目的ip } __attribute__((packed))IP_HEADER, *PIP_HEADER ;
a.版本:指IP協議的版本,通訊雙方使用的IP協議版本必須一致。通常的值爲0100(IPv4),0110(IPv6)。
b.首部長度:長度4比特。這個字段的做用是爲了描述IP包頭的長度,由於在IP包頭中有變長的可選部分。該部分佔4個bit位,單位爲32bit(4個字節),即本區域值=IP頭部長度(單位爲bit)/(8*4,所以,一個IP包頭的長度最長爲「1111」,即15*4=60個字節。IP包頭最小長度爲20字節。
c.優先級與服務類型:長度8比特,定義了數據包傳輸的緊急程度以及時延、可靠性、傳輸成本等。
d.總長度:16比特,以字節爲單位描述IP包的總長度(包括頭部和數據兩部分),最大值爲65535。第二行中標識符、標誌和段偏移量一般聯合使用,用於數據拆分時的分組和重組。
e.標識符:對於上層發來的較大的數據包,每每須要拆分。路由器將一個大包進行拆分後,拆出來的全部部分被標上相同的值,該值即爲標識符,用於告訴目的端哪些包屬於同一個大包。
f.標誌:長度3比特。該字段第一位不使用。第二位是DF(Don't Fragment)位,DF位設爲1時代表路由器不能對該上層數據包分段。若是一個上層數據包沒法在不分段的狀況下進行轉發,則路由器會丟棄該上層數據包並返回一個錯誤信息。第三位是MF(More Fragments)位,當路由器對一個上層數據包分段,則路由器會在除了最後一個分段的IP包的包頭中將MF位設爲1。
g.段偏移量:長度13比特,表示一個數據包在原先被拆分前的大包中的位置。接收端據此來還原和組裝IP包。
h.TTL:表示IP包的生存時間,長度8比特。長度8比特。當IP包進行傳送時,先會對該字段賦予某個特定的值。當IP包通過每個沿途的路由器的時候,每一個沿途的路由器會將IP包的TTL值減小1。若是TTL減小爲0,則該IP包會被丟棄。這個字段能夠防止因爲路由環路而致使IP包在網絡中不停被轉發。
i.協議號:長度8比特,標識上一層即傳輸層在本次數據傳輸中所使用的協議。好比6表明TCP,17表明UDP等
j.首部校驗和:長度16位。用來作IP頭部的正確性檢測,但不包含數據部分。 由於每一個路由器要改變TTL的值,因此路由器會爲每一個經過的數據包從新計算這個值。
k.源地址:長度32比特,標識IP包的起源地址。
l.目標地址:長度32比特,表示IP包的目的地址。
m.可選項:可變長字段,主要用於測試,由起源設備跟據須要改寫。
n.填充:由於IP包頭長度(Header Length)部分的單位爲32bit,因此IP包頭的長度必須爲32bit的整數倍。所以,在可選項後面,IP協議會填充若干個0,以達到32bit的整數倍。
二、IP選項
「通常」的IP頭是20字節,但IP頭有選項設置,不能直接從偏移21字節處讀取數據。IP頭有個長度字段能夠知道頭長度是否大於20字節。
一般第一個字節的二進制值是:01000101,分紅兩個部分:
0100 = 4 表示IP版本 0101 = 5 表示IP頭32 bit的塊數,5 x 32 bits = 160 bits or 20 bytes
若是第一字節第二部分的值大於5,那麼表示頭有IP選項。
下面介紹有過濾方法
0100 0101 : 第一字節的二進制
0000 1111 : 與操做
<=========
0000 0101 : 結果
正確的過濾方法:
tcpdump -i eth1 'ip[0] & 15 > 5' 或 tcpdump -i eth1 'ip[0] & 0x0f > 5'
三、分片標記
當發送端的MTU大於到目的路徑鏈路上的MTU時就會被分片,分片信息在IP頭的第七和第八字節:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Bit 0: 保留,必須是0
Bit 1: (DF) 0 = 可能分片, 1 = 不分片
Bit 2: (MF) 0 = 最後的分片, 1 = 還有分片
Fragment Offset字段只有在分片的時候才使用。
要抓帶DF位標記的不分片的包,第七字節的值應該是:
01000000 = 64
tcpdump -i eth1 'ip[6] = 64'
四、抓分片包
4.一、匹配MF,分片包
tcpdump -i eth1 'ip[6] = 32'
最後分片包的開始3位是0,可是有Fragment Offset字段。
4.二、匹配分片和最後分片
tcpdump -i eth1 '((ip[6:2] > 0) and (not ip[6] = 64))'
測試分片能夠用下面的命令:
ping -M want -s 3000 192.168.1.1
五、匹配小TTL
TTL字段在第九字節,而且正好是完整的一個字節,TTL最大值是255,二進制爲11111111。
能夠用下面的命令驗證一下:
$ ping -M want -s 3000 -t 256 192.168.1.200 ping: ttl 256 out of range
+-+-+-+-+-+-+-+-+
| Time to Live | +-+-+-+-+-+-+-+-+
a.在網關能夠用下面的命令看看網絡中誰在使用traceroute
tcpdump -i eth1 'ip[8] < 5'
六、抓大於X字節的包
a.大於600字節
tcpdump -i eth1 'ip[2:2] > 600'
七、更多的過濾方式
首先仍是須要知道TCP基本結構
a.TCP頭
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |C|E|U|A|P|R|S|F| | | Offset| Res. |W|C|R|C|S|S|Y|I| Window | | | |R|E|G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/*TCP頭定義,共20個字節*/ typedef struct _TCP_HEADER { short m_sSourPort; // 源端口號16bit short m_sDestPort; // 目的端口號16bit unsigned int m_uiSequNum; // 序列號32bit unsigned int m_uiAcknowledgeNum; // 確認號32bit short m_sHeaderLenAndFlag; // 前4位:TCP頭長度;中6位:保留;後6位:標誌位 short m_sWindowSize; // 窗口大小16bit short m_sCheckSum; // 檢驗和16bit short m_surgentPointer; // 緊急數據偏移量16bit }__attribute__((packed))TCP_HEADER, *PTCP_HEADER; /*TCP頭中的選項定義 kind(8bit)+Length(8bit,整個選項的長度,包含前兩部分)+內容(若是有的話) KIND = 1表示 無操做NOP,無後面的部分 2表示 maximum segment 後面的LENGTH就是maximum segment選項的長度(以byte爲單位,1+1+內容部分長度) 3表示 windows scale 後面的LENGTH就是 windows scale選項的長度(以byte爲單位,1+1+內容部分長度) 4表示 SACK permitted LENGTH爲2,沒有內容部分 5表示這是一個SACK包 LENGTH爲2,沒有內容部分 8表示時間戳,LENGTH爲10,含8個字節的時間戳 */
16位源端口號和16位目的端口號。 32位序號:一次TCP通訊過程當中某一個傳輸方向上的字節流的每一個字節的編號,經過這個來確認發送的數據有序,好比如今序列號爲1000,發送了1000,下一個序列號就是2000。 32位確認號:用來響應TCP報文段,給收到的TCP報文段的序號加1,三握時還要攜帶本身的序號。 4位頭部長度:標識該TCP頭部有多少個4字節,共表示最長15*4=60字節。同IP頭部。 6位保留。6位標誌。URG(緊急指針是否有效)ACK(表示確認號是否有效)PSH(提示接收端應用程序應該當即從TCP接收緩衝區讀走數據)RST(表示要求對方從新創建鏈接)SYN(表示請求創建一個鏈接)FIN(表示通知對方本端要關閉鏈接) 16位窗口大小:TCP流量控制的一個手段,用來告訴對端TCP緩衝區還能容納多少字節。 16位校驗和:由發送端填充,接收端對報文段執行CRC算法以檢驗TCP報文段在傳輸中是否損壞。 16位緊急指針:一個正的偏移量,它和序號段的值相加表示最後一個緊急數據的下一字節的序號。 標誌位字段(U、A、P、R、S、F):佔6比特。各比特的含義以下: URG:緊急指針(urgent pointer)有效。 ACK:確認序號有效。 PSH:接收方應該儘快將這個報文段交給應用層。 RST:重建鏈接。 SYN:發起一個鏈接。 FIN:釋放一個鏈接。 窗口大小字段:佔16比特。此字段用來進行流量控制。單位爲字節數,這個值是本機指望一次接收的字節數。 TCP校驗和字段:佔16比特。對整個TCP報文段,即TCP頭部和TCP數據進行校驗和計算,並由目標端進行驗證。 緊急指針字段:佔16比特。它是一個偏移量,和序號字段中的值相加表示緊急數據最後一個字節的序號。 選項字段:佔32比特。可能包括"窗口擴大因子"、"時間戳"等選項。
a.抓取源端口大於1024的TCP數據包
tcpdump -i eth1 'tcp[0:2] > 1024'
匹配TCP數據包的特殊標記
TCP標記定義在TCP頭的第十四個字節
+-+-+-+-+-+-+-+-+
|C|E|U|A|P|R|S|F|
|W|C|R|C|S|S|Y|I|
|R|E|G|K|H|T|N|N|
+-+-+-+-+-+-+-+-+
只抓SYN包,第十四字節是二進制的00000010,也就是十進制的2
tcpdump -i eth1 'tcp[13] = 2' 抓SYN, ACK (00010010 or 18) tcpdump -i eth1 'tcp[13] = 18' 抓SYN或者SYN-ACK tcpdump -i eth1 'tcp[13] & 2 = 2' 抓PSH-ACK tcpdump -i eth1 'tcp[13] = 24' 抓全部包含FIN標記的包(FIN一般和ACK一塊兒,表示幽會完了,回見) tcpdump -i eth1 'tcp[13] & 1 = 1' 抓RST tcpdump -i eth1 'tcp[13] & 4 = 4'
八、經常使用的字段偏移名字
8.一、tcpdump考慮了一些數字恐懼症者的需求,提供了部分經常使用的字段偏移名字:
a.icmptype (ICMP類型字段)
b.icmpcode (ICMP符號字段)
c.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-push, tcp-ack, tcp-urg
這樣上面按照TCP標記位抓包的就能夠寫直觀的表達式了:
a.只抓SYN包
tcpdump -i eth1 'tcp[tcpflags] = tcp-syn'
b.抓SYN、ACK
tcpdump -i eth1 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0'
九、抓SMTP數據
tcpdump -i eth1 '((port 25) and (tcp[(tcp[12]>>2):4] = 0x4d41494c))'
抓取數據區開始爲"MAIL"的包,"MAIL"的十六進制爲0x4d41494c。
十、抓HTTP GET數據
tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x47455420'
"GET "的十六進制是47455420
十一、抓SSH返回
tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x5353482D'
"SSH-"的十六進制是0x5353482D
tcpdump -i eth1 '(tcp[(tcp[12]>>2):4] = 0x5353482D) and (tcp[((tcp[12]>>2)+4):2] = 0x312E)'
5、比較經常使用的方式
若是是爲了查看數據內容,建議用tcpdump -s 0 -w filename把數據包都保存下來,而後用wireshark的Follow TCP Stream/Follow UDP Stream來查看整個會話的內容。-s 0是抓取完整數據包,不然默認只抓68字節。用tcpflow也能夠方便的獲取TCP會話內容,支持tcpdump的各類表達式。
一、UDP頭
0 7 8 15 16 23 24 31 +--------+--------+--------+--------+ | Source | Destination | | Port | Port | +--------+--------+--------+--------+ | | | | Length | Checksum | +--------+--------+--------+--------+ | | | DATA ... | +-----------------------------------+
/*UDP頭定義,共8個字節*/ typedef struct _UDP_HEADER { unsigned short m_usSourPort; // 源端口號16bit unsigned short m_usDestPort; // 目的端口號16bit unsigned short m_usLength; // 數據包長度16bit unsigned short m_usCheckSum; // 校驗和16bit }__attribute__((packed))UDP_HEADER, *PUDP_HEADER;
a.抓DNS請求數據
tcpdump -i eth1 udp dst port 53
二、系統測試
-c參數對於運維人員來講也比較經常使用,由於流量比較大的服務器,靠人工CTRL+C仍是抓的太多,甚至致使服務器宕機,因而能夠用-c參數指定抓多少個包。
time tcpdump -nn -i eth0 'tcp[tcpflags] = tcp-syn' -c 10000 > /dev/null
上面的命令計算抓10000個SYN包花費多少時間,能夠判斷訪問量大概是多少。
三、tcpdump 與 wireshark
Wireshark(之前是ethereal)是Windows下很是簡單易用的抓包工具。但在Linux下很難找到一個好用的圖形化抓包工具。
還好有Tcpdump。咱們能夠用Tcpdump + Wireshark 的完美組合實現:在 Linux 裏抓包,而後在Windows 裏分析包。
tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
tcp: ip icmp arp rarp 和 tcp、udp、icmp這些選項等都要放到第一個參數的位置,用來過濾數據報的類型 -i eth1 : 只抓通過接口eth1的包 -t : 不顯示時間戳 -s 0 : 抓取數據包時默認抓取長度爲68字節。加上-S 0 後能夠抓到完整的數據包 -c 100 : 只抓取100個數據包 dst port ! 22 : 不抓取目標端口是22的數據包 src net 192.168.1.0/24 : 數據包的源網絡地址爲192.168.1.0/24 -w ./target.cap : 保存成cap文件,方便用ethereal(即wireshark)分析
四、使用tcpdump 抓取HTTP包
tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854
0x4745 爲"GET"前兩個字母"GE",0x4854 爲"HTTP"前兩個字母"HT"。
tcpdump 對截獲的數據並無進行完全解碼,數據包內的大部份內容是使用十六進制的形式直接打印輸出的。顯然這不利於分析網絡故障,一般的解決辦法是先使用帶-w參數的tcpdump 截獲數據並保存到文件中,而後再使用其餘程序(如Wireshark)進行解碼分析。固然也應該定義過濾規則,以免捕獲的數據包填滿整個硬盤。
基本上tcpdump總的的輸出格式爲:系統時間 來源主機.端口 > 目標主機.端口 數據包參數
---------------------------------------------書山有路勤爲徑,學海無涯苦做舟--------------------------------------------------------