關於Tcpdump抓包總結

1、簡介

tcpdump是一個用於截取網絡分組,並輸出分組內容的工具。憑藉強大的功能和靈活的截取策略,使其成爲類UNIX系統下用於網絡分析和問題排查的首選工具html

tcpdump提供了源代碼,公開了接口,所以具有很強的可擴展性,對於網絡維護和入侵者都是很是有用的工具linux

tcpdump 支持針對網絡層、協議、主機、網絡或端口的過濾,並提供and、or、not等邏輯語句來幫助你去掉無用的信息git

When tcpdump finishes capturing packets, it will report counts of:github

packets ``captured'' (this is the number of packets that  tcpdump has received and processed);
packets ``received by filter'' (the meaning of this depends on the OS on which you're running  tcpdump, and possibly on the way the OS was configured - if a filter was specified on the command line, on some OSes it counts packets regardless of whether they were matched by the filter expression and, even if they were matched by the filter expression, regardless of whether  tcpdump has read and processed them yet, on other OSes it counts only packets that were matched by the filter expression regardless of whether  tcpdump has read and processed them yet, and on other OSes it counts only packets that were matched by the filter expression and were processed by  tcpdump);
packets ``dropped by kernel'' (this is the number of packets that were dropped, due to a lack of buffer space, by the packet capture mechanism in the OS on which  tcpdump is running, if the OS reports that information to applications; if not, it will be reported as 0).

2、語法

完整的英文文檔:https://www.tcpdump.org/tcpdump_man.html算法

  • -A 以ASCII格式打印出全部分組,並將鏈路層的頭最小化。 express

  • -c 在收到指定的數量的分組後,tcpdump就會中止。 windows

  • -C 在將一個原始分組寫入文件以前,檢查文件當前的大小是否超過了參數file_size 中指定的大小。若是超過了指定大小,則關閉當前文件,而後在打開一個新的文件。參數 file_size 的單位是兆字節(是1,000,000字節,而不是1,048,576字節)。 安全

  • -d 將匹配信息包的代碼以人們可以理解的彙編格式給出。 bash

  • -dd 將匹配信息包的代碼以C語言程序段的格式給出。 服務器

  • -ddd 將匹配信息包的代碼以十進制的形式給出。 

  • -D 打印出系統中全部能夠用tcpdump截包的網絡接口。 

  • -e 在輸出行打印出數據鏈路層的頭部信息。 

  • -E 用spi@ipaddr algo:secret解密那些以addr做爲地址,而且包含了安全參數索引值spi的IPsec ESP分組。 

  • -f 將外部的Internet地址以數字的形式打印出來。 

  • -F 從指定的文件中讀取表達式,忽略命令行中給出的表達式。 

  • -i 指定監聽的網絡接口。 

  • -l 使標準輸出變爲緩衝行形式,能夠把數據導出到文件。 

  • -L 列出網絡接口的已知數據鏈路。 

  • -m 從文件module中導入SMI MIB模塊定義。該參數能夠被使用屢次,以導入多個MIB模塊。 

  • -M 若是tcp報文中存在TCP-MD5選項,則須要用secret做爲共享的驗證碼用於驗證TCP-MD5選選項摘要(詳情可參考RFC 2385)。 

  • -b 在數據-鏈路層上選擇協議,包括ip、arp、rarp、ipx都是這一層的。 

  • -n 不把網絡地址轉換成名字。 

  • -nn 不進行端口名稱的轉換。 

  • -N 不輸出主機名中的域名部分。例如,‘nic.ddn.mil‘只輸出’nic‘。 

  • -t 在輸出的每一行不打印時間戳。 

  • -O 不運行分組分組匹配(packet-matching)代碼優化程序。 

  • -P 不將網絡接口設置成混雜模式。 

  • -q 快速輸出。只輸出較少的協議信息。 

  • -r 從指定的文件中讀取包(這些包通常經過-w選項產生)。 

  • -S 將tcp的序列號以絕對值形式輸出,而不是相對值。 

  • -s 從每一個分組中讀取最開始的snaplen個字節,而不是默認的68個字節。 

  • -T 將監聽到的包直接解釋爲指定的類型的報文,常見的類型有rpc遠程過程調用)和snmp(簡單網絡管理協議;)。 

  • -t 不在每一行中輸出時間戳。 

  • -tt 在每一行中輸出非格式化的時間戳。 

  • -ttt 輸出本行和前面一行之間的時間差。 

  • -tttt 在每一行中輸出由date處理的默認格式的時間戳。 

  • -u 輸出未解碼的NFS句柄。 

  • -v 輸出一個稍微詳細的信息,例如在ip包中能夠包括ttl和服務類型的信息。 

  • -vv 輸出詳細的報文信息。 

  • -w 直接將分組寫入文件中,而不是不分析並打印出來。

以太網幀的封包格式爲:Frame=Ethernet Header +IP Header +TCP Header +TCP Segment Data

  • Ethernet Header =14 Byte =Dst Physical Address(6 Byte)+ Src Physical Address(6 Byte)+Type(2 Byte),以太網幀頭如下稱之爲數據幀。

  • IP Header =20 Byte(without options field),數據在IP層稱爲Datagram,分片稱爲Fragment。

  • TCP Header = 20 Byte(without options field),數據在TCP層稱爲Stream,分段稱爲Segment(UDP中稱爲Message)。

  • 54個字節後爲TCP數據負載部分(Data Portion),即應用層用戶數據。

Ethernet Header如下的IP數據報最大傳輸單位爲MTU(Maximum Transmission Unit,Effect of short board),對於大多數使用以太網的局域網來講,MTU=1500。

TCP數據包每次可以傳輸的最大數據分段爲MSS,爲了達到最佳的傳輸效能,在創建TCP鏈接時雙方將協商MSS值——雙方提供的MSS值中的最小值爲此次鏈接的最大MSS值。MSS每每基於MTU計算出來,一般MSS=MTU-sizeof(IP Header)-sizeof(TCP Header)=1500-20-20=1460。

這樣,數據通過本地TCP層分段後,交給本地IP層,在本地IP層就不須要分片了。可是在下一跳路由(Next Hop)的鄰居路由器上可能發生IP分片!由於路由器的網卡的MTU可能小於須要轉發的IP數據報的大小。

這時候,在路由器上可能發生兩種狀況:

(1)若是源發送端設置了這個IP數據包能夠分片(May Fragment,DF=0),路由器將IP數據報分片後轉發。

(2)若是源發送端設置了這個IP數據報不能夠分片(Don’t Fragment,DF=1),路由器將IP數據報丟棄,併發送ICMP分片錯誤消息給源發送端。

3、實例

一、默認啓動

tcpdump -vv

普通狀況下,直接啓動tcpdump將監視第一個網絡接口上全部流過的數據包。

二、過濾主機

tcpdump -i eth1 host 192.168.1.1
tcpdump -i eth1 src host 192.168.1.1
tcpdump -i eth1 dst host 192.168.1.1

抓取全部通過eth1,目的或源地址是192.168.1.1的網絡數據

指定源地址,192.168.1.1

指定目的地址,192.168.1.1

三、過濾端口

tcpdump -i eth1 port 25
tcpdump -i eth1 src port 25
tcpdump -i eth1 dst port 25

抓取全部通過eth1,目的或源端口是25的網絡數據

指定源端口

指定目的端口

四、網絡過濾

tcpdump -i eth1 net 192.168
tcpdump -i eth1 src net 192.168
tcpdump -i eth1 dst net 192.168

五、協議過濾

tcpdump -i eth1 arp
tcpdump -i eth1 ip
tcpdump -i eth1 tcp
tcpdump -i eth1 udp
tcpdump -i eth1 icmp

六、經常使用表達式

非 : ! or "not" (去掉雙引號)  
且 : && or "and"  
或 : || or "or"

抓取全部通過eth1,目的地址是192.168.1.254或192.168.1.200端口是80的TCP數

tcpdump -i eth1 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'

抓取全部通過eth1,目標MAC地址是00:01:02:03:04:05的ICMP數據

tcpdump -i eth1 '((icmp) and ((ether dst host 00:01:02:03:04:05)))'

抓取全部通過eth1,目的網絡是192.168,但目的主機不是192.168.1.200的TCP數據

tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'

4、高級過濾方式

首先了解如何從包頭過濾信息

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 ;
  •  版本:指IP協議的版本,通訊雙方使用的IP協議版本必須一致。通常的值爲0100(IPv4),0110(IPv6)。
  •  首部長度:長度4比特。這個字段的做用是爲了描述IP包頭的長度,由於在IP包頭中有變長的可選部分。該部分佔4個bit位,單位爲32bit(4個字節),即本區域值= IP頭部長度(單位爲bit)/(8*4),所以,一個IP包頭的長度最長爲「1111」,即15*4=60個字節。IP包頭最小長度爲20字節。

  • 優先級與服務類型:長度8比特,定義了數據包傳輸的緊急程度以及時延、可靠性、傳輸成本等。

  •    總長度:16比特,以字節爲單位描述IP包的總長度(包括頭部和數據兩部分),最大值爲65535。第二行中標識符、標誌和段偏移量一般聯合使用,用於數據拆分時的分組和重組。

  •    標識符:對於上層發來的較大的數據包,每每須要拆分。路由器將一個大包進行拆分後,拆出來的全部部分被標上相同的值,該值即爲標識符,用於告訴目的端哪些包屬於同一個大包。

  •    標誌:長度3比特。該字段第一位不使用。第二位是DF(Don't Fragment)位,DF位設爲1時代表路由器不能對該上層數據包分段。若是一個上層數據包沒法在不分段的狀況下進行轉發,則路由器會丟棄該上層數據包並返回一個錯誤信息。第三位是MF(More Fragments)位,當路由器對一個上層數據包分段,則路由器會在除了最後一個分段的IP包的包頭中將MF位設爲1。

  •    段偏移量:長度13比特,表示一個數據包在原先被拆分前的大包中的位置。接收端據此來還原和組裝IP包。

  •    TTL:表示IP包的生存時間,長度8比特。長度8比特。當IP包進行傳送時,先會對該字段賦予某個特定的值。當IP包通過每個沿途的路由器的時候,每一個沿途的路由器會將IP包的TTL值減小1。若是TTL減小爲0,則該IP包會被丟棄。這個字段能夠防止因爲路由環路而致使IP包在網絡中不停被轉發。

  •    協議號:長度8比特,標識上一層即傳輸層在本次數據傳輸中所使用的協議。好比6表明TCP,17表明UDP等

  •    首部校驗和:長度16位。用來作IP頭部的正確性檢測,但不包含數據部分。 由於每一個路由器要改變TTL的值,因此路由器會爲每一個經過的數據包從新計算這個值。

  •    源地址:長度32比特,標識IP包的起源地址。

  •    目標地址:長度32比特,表示IP包的目的地址。

  •    可選項:可變長字段,主要用於測試,由起源設備跟據須要改寫。

  •    填充:由於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'

四、抓分片包

  • 匹配MF,分片包
tcpdump -i eth1 'ip[6] = 32'

最後分片包的開始3位是0,可是有Fragment Offset字段。

  • 匹配分片和最後分片
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 | +-+-+-+-+-+-+-+-+ 
  • 在網關能夠用下面的命令看看網絡中誰在使用traceroute
tcpdump -i eth1 'ip[8] < 5'

六、抓大於X字節的包

  • 大於600字節
tcpdump -i eth1 'ip[2:2] > 600'

七、更多的過濾方式

首先仍是須要知道TCP基本結構

  • 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比特。可能包括"窗口擴大因子"、"時間戳"等選項。

 

  • 抓取源端口大於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'

八、經常使用的字段偏移名字

tcpdump考慮了一些數字恐懼症者的需求,提供了部分經常使用的字段偏移名字:

  • icmptype (ICMP類型字段)

  • icmpcode (ICMP符號字段)

  • 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標記位抓包的就能夠寫直觀的表達式了:

  • 只抓SYN包
tcpdump -i eth1 'tcp[tcpflags] = tcp-syn'
  • 抓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;
  • 抓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總的的輸出格式爲:系統時間 來源主機.端口 > 目標主機.端口 數據包參數

參考資料

https://linuxwiki.github.io/NetTools/tcpdump.html

https://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html

https://blog.wains.be/2007/2007-10-01-tcpdump-advanced-filters/ (原文)

https://www.cnblogs.com/shenpengyan/p/5912567.html

相關文章
相關標籤/搜索