關於Tcpdump抓包總結


一、簡介

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

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

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

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

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).

二、語法

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

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

  • -c 在收到指定的數量的分組后,tcpdump就會停止。 

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

  • -d 將匹配信息包的代碼以人們能夠理解的匯編格式給出。 

  • -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分片錯誤消息給源發送端。

三、實例

1、默認啟動

tcpdump -vv

普通情況下,直接啟動tcpdump將監視第一個網絡接口上所有流過的數據包。

2、過濾主機

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

3、過濾端口

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

抓取所有經過eth1,目的或源端口是25的網絡數據

指定源端口

指定目的端口

4、網絡過濾

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

5、協議過濾

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

6、常用表達式

非 : ! 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)))'

四、高級過濾方式

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

proto[x:y]          : 過濾從x字節開始的y字節數。比如ip[2:2]過濾出3、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

操作符 : >, <, >=, <=, =, !=

1、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的整數倍。

2、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' 

3、分片標記

當發送端的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字段。

  • 匹配分片和最后分片
tcpdump -i eth1 '((ip[6:2] > 0) and (not ip[6] = 64))'

測試分片可以用下面的命令:

ping -M want -s 3000 192.168.1.1

5、匹配小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'

6、抓大於X字節的包

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

7、更多的過濾方式

首先還是需要知道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'

8、常用的字段偏移名字

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'

9、抓SMTP數據

tcpdump -i eth1 '((port 25) and (tcp[(tcp[12]>>2):4] = 0x4d41494c))'

抓取數據區開始為"MAIL"的包,"MAIL"的十六進制為0x4d41494c。

10、抓HTTP GET數據

tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x47455420'

"GET "的十六進制是47455420

11、抓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)'

五、比較常用的方式

如果是為了查看數據內容,建議用tcpdump -s 0 -w filename把數據包都保存下來,然后用wireshark的Follow TCP Stream/Follow UDP Stream來查看整個會話的內容。-s 0是抓取完整數據包,否則默認只抓68字節。用tcpflow也可以方便的獲取TCP會話內容,支持tcpdump的各種表達式。

1、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

2、系統測試

-c參數對於運維人員來說也比較常用,因為流量比較大的服務器,靠人工CTRL+C還是抓的太多,甚至導致服務器宕機,於是可以用-c參數指定抓多少個包。

time tcpdump -nn -i eth0 'tcp[tcpflags] = tcp-syn' -c 10000 > /dev/null

上面的命令計算抓10000個SYN包花費多少時間,可以判斷訪問量大概是多少。 

3、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)分析

4、使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM