主頁 > 作業系統 > 全網最詳細的 tcpdump 使用指南

全網最詳細的 tcpdump 使用指南

2020-09-15 08:54:43 作業系統

今天要給大家介紹的一個 Unix 下的一個 網路資料采集分析工具,也就是我們常說的抓包工具,

與它功能類似的工具有 wireshark ,不同的是,wireshark 有圖形化界面,而 tcpdump 則只有命令列,

由于我本人更習慣使用命令列的方式進行抓包,因此今天先跳過 wireshark,直接給大家介紹這個 tcpdump 神器,

這篇文章,我肝了好幾天,借助于Linux 的 man 幫助命令,我把 tcpdump 的用法全部研究了個遍,才形成了本文,不夸張的說,應該可以算是中文里把 tcpdump 講得最清楚明白,并且還最全的文章了(至少我從百度、谷歌的情況來看),所以本文值得你收藏分享,就怕你錯過了,就再也找不到像這樣把 tcpdump 講得直白而且特全的文章了,

在講解之前,有兩點需要宣告:

  1. 第三節到第六節里的 tcpdump 命令示例,只為了說明引數的使用,并不一定就能抓到包,如果要精準抓到你所需要的包,需要配合第五節的邏輯邏輯運算子進行組合搭配,
  2. 不同 Linux 發行版下、不同版本的 tcpdump 可能有小許差異, 本文是基于 CentOS 7.2 的 4.5.1 版本的tcpdump 進行學習的,若在你的環境中無法使用,請參考 man tcpdump 進行針對性學習,

1. tcpdump 核心引數圖解

大家都知道,網路上的流量、資料包,非常的多,因此要想抓到我們所需要的資料包,就需要我們定義一個精準的過濾器,把這些目標資料包,從巨大的資料包網路中抓取出來,

所以學習抓包工具,其實就是學習如何定義過濾器的程序,

而在 tcpdump 的世界里,過濾器的實作,都是通過一個又一個的引陣列合起來,一個引數不夠精準,那就再加一個,直到我們能過濾掉無用的資料包,只留下我們感興趣的資料包,

tcpdump 的引數非常的多,初學者在沒有掌握 tcpdump 時,會對這個命令的眾多引數產生很多的疑惑,

就比如下面這個命令,我們要通過 host 引數指定 host ip 進行過濾

$ tcpdump host 192.168.10.100

主程式 + 引數名+ 引數值 這樣的組合才是我們正常認知里面命令列該有的樣子,

可 tcpdump 卻不走尋常路,我們居然還可以在 host 前再加一個限定詞,來縮小過濾的范圍?

$ tcpdump src host 192.168.10.100

從字面上理解,確實很容易理解,但是這不符合撰寫命令列程式的正常邏輯,導致我們會有所疑慮:

  1. 除了 src ,dst,可還有其它可以用的限定詞?

  2. src,host 應該如何理解它們,叫引數名?不合適,因為 src 明顯不合適,

如果你在網上看到有關 tcpdump 的博客、教程,無一不是給你一個引陣列合,告訴你這是實作了怎樣的一個過濾器?這樣的教學方式,很容易讓你依賴別人的文章來使用 tcpdump,而不能將 tcpdump 這樣神器消化,達到靈活應用,靈活搭配過濾器的效果,

上面加了 src 本身就顛覆了我們的認知,你可知道在 src 之前還可以加更多的條件,比如 tcp, udp, icmp 等詞,在你之前的基礎上再過濾一層,

$ tcpdump tcp src host 192.168.10.100

這種引數的不確定性,讓大多數人對 tcpdump 的學習始終無法得其精髓,

因此,在學習 tcpdump 之前,我覺得有必要要先讓你知道:tcpdump 的引數是如何組成的?這非常重要,

為此,我畫了一張圖,方便你直觀的理解 tcpdump 的各種引數:

  1. option 可選引數:將在后邊一一解釋,
  2. proto 類過濾器:根據協議進行過濾,可識別的關鍵詞有: tcp, udp, icmp, ip, ip6, arp, rarp,ether,wlan, fddi, tr, decnet
  3. type 類過濾器:可識別的關鍵詞有:host, net, port, portrange,這些詞后邊需要再接引數,
  4. direction 類過濾器:根據資料流向進行過濾,可識別的關鍵字有:src, dst,同時你可以使用邏輯運算子進行組合,比如 src or dst

proto、type、direction 這三類過濾器的內容比較簡單,也最常用,因此我將其放在最前面,也就是 第三節:常規過濾規則一起介紹,

而 option 可選的引數非常多,有的甚至也不經常用到,因此我將其放到后面一點,也就是 第四節:可選引數決議

當你看完前面六節,你對 tcpdump 的認識會上了一個臺階,至少能夠滿足你 80% 的使用需求,

你一定會問了,還有 20% 呢?

其實 tcpdump 還有一些過濾關鍵詞,它不符合以上四種過濾規則,可能需要你單獨記憶,關于這部分我會在 第六節:特殊過濾規則 里進行介紹,

2. 理解 tcpdump 的輸出

2.1 輸出內容結構

tcpdump 輸出的內容雖然多,卻很規律,

這里以我隨便抓取的一個 tcp 包為例來看一下

21:26:49.013621 IP 172.20.20.1.15605 > 172.20.20.2.5920: Flags [P.], seq 49:97, ack 106048, win 4723, length 48

從上面的輸出來看,可以總結出:

  1. 第一列:時分秒毫秒 21:26:49.013621
  2. 第二列:網路協議 IP
  3. 第三列:發送方的ip地址+埠號,其中172.20.20.1是 ip,而15605 是埠號
  4. 第四列:箭頭 >, 表示資料流向
  5. 第五列:接收方的ip地址+埠號,其中 172.20.20.2 是 ip,而5920 是埠號
  6. 第六列:冒號
  7. 第七列:資料包內容,包括Flags 識別符號,seq 號,ack 號,win 視窗,資料長度 length,其中 [P.] 表示 PUSH 標志位為 1,更多識別符號見下面

2.2 Flags 識別符號

使用 tcpdump 抓包后,會遇到的 TCP 報文 Flags,有以下幾種:

  • [S] : SYN(開始連接)
  • [P] : PSH(推送資料)
  • [F] : FIN (結束連接)
  • [R] : RST(重置連接)
  • [.] : 沒有 Flag (意思是除上面四種型別外的其他情況,有可能是 ACK 也有可能是 URG)

3. 常規過濾規則

3.1 基于IP地址過濾:host

使用 host 就可以指定 host ip 進行過濾

$ tcpdump host 192.168.10.100

資料包的 ip 可以再細分為源ip和目標ip兩種

# 根據源ip進行過濾
$ tcpdump -i eth2 src 192.168.10.100

# 根據目標ip進行過濾
$ tcpdump -i eth2 dst 192.168.10.200

3.2 基于網段進行過濾:net

若你的ip范圍是一個網段,可以直接這樣指定

$ tcpdump net 192.168.10.0/24

網段同樣可以再細分為源網段和目標網段

# 根據源網段進行過濾
$ tcpdump src net 192.168

# 根據目標網段進行過濾
$ tcpdump dst net 192.168

3.3 基于埠進行過濾:port

使用 port 就可以指定特定埠進行過濾

$ tcpdump port 8088

埠同樣可以再細分為源埠,目標埠

# 根據源埠進行過濾
$ tcpdump src port 8088

# 根據目標埠進行過濾
$ tcpdump dst port 8088

如果你想要同時指定兩個埠你可以這樣寫

$ tcpdump port 80 or port 8088

但也可以簡寫成這樣

$ tcpdump port 80 or 8088

如果你的想抓取的不再是一兩個埠,而是一個范圍,一個一個指定就非常麻煩了,此時你可以這樣指定一個埠段,

$ tcpdump portrange 8000-8080
$ tcpdump src portrange 8000-8080
$ tcpdump dst portrange 8000-8080

對于一些常見協議的默認埠,我們還可以直接使用協議名,而不用具體的埠號

比如 http == 80,https == 443 等

$ tcpdump tcp port http

3.4 基于協議進行過濾:proto

常見的網路協議有:tcp, udp, icmp, http, ip,ipv6 等

若你只想查看 icmp 的包,可以直接這樣寫

$ tcpdump icmp

protocol 可選值:ip, ip6, arp, rarp, atalk, aarp, decnet, sca, lat, mopdl, moprc, iso, stp, ipx, or netbeui

3.5 基本IP協議的版本進行過濾

當你想查看 tcp 的包,你也許會這樣子寫

$ tcpdump tcp

這樣子寫也沒問題,就是不夠精準,為什么這么說呢?

ip 根據版本的不同,可以再細分為 IPv4 和 IPv6 兩種,如果你只指定了 tcp,這兩種其實都會包含在內,

那有什么辦法,能夠將 IPv4 和 IPv6 區分開來呢?

很簡單,如果是 IPv4 的 tcp 包 ,就這樣寫(友情提示:數字 6 表示的是 tcp 在ip報文中的編號,)

$ tcpdump 'ip proto tcp'

# or

$ tcpdump ip proto 6

# or

$ tcpdump 'ip protochain tcp'

# or 

$ tcpdump ip protochain 6

而如果是 IPv6 的 tcp 包 ,就這樣寫

$ tcpdump 'ip6 proto tcp'

# or

$ tcpdump ip6 proto 6

# or

$ tcpdump 'ip6 protochain tcp'

# or 

$ tcpdump ip6 protochain 6

關于上面這幾個命令示例,有兩點需要注意:

  1. 跟在 proto 和 protochain 后面的如果是 tcp, udp, icmp ,那么過濾器需要用引號包含,這是因為 tcp,udp, icmp 是 tcpdump 的關鍵字,
  2. 跟在ip 和 ip6 關鍵字后面的 proto 和 protochain 是兩個新面孔,看起來用法類似,它們是否等價,又有什么區別呢?

關于第二點,網路上沒有找到很具體的答案,我只能通過 man tcpdump 的提示, 給出自己的個人猜測,但不保證正確,

proto 后面跟的 <protocol> 的關鍵詞是固定的,只能是 ip, ip6, arp, rarp, atalk, aarp, decnet, sca, lat, mopdl, moprc, iso, stp, ipx, or netbeui 這里面的其中一個,

而 protochain 后面跟的 protocol 要求就沒有那么嚴格,它可以是任意詞,只要 tcpdump 的 IP 報文頭部里的 protocol 欄位為 <protocol> 就能匹配上,

理論上來講,下面兩種寫法效果是一樣的

$ tcpdump 'ip && tcp'
$ tcpdump 'ip proto tcp'

同樣的,這兩種寫法也是一樣的

$ tcpdump 'ip6 && tcp'
$ tcpdump 'ip6 proto tcp'

4. 可選引數決議

4.1 設定不決議域名提升速度

  • -n:不把ip轉化成域名,直接顯示 ip,避免執行 DNS lookups 的程序,速度會快很多
  • -nn:不把協議和埠號轉化成名字,速度也會快很多,
  • -N:不列印出host 的域名部分.,比如,,如果設定了此選現,tcpdump 將會列印'nic' 而不是 'nic.ddn.mil'.

4.2 過濾結果輸出到檔案

使用 tcpdump 工具抓到包后,往往需要再借助其他的工具進行分析,比如常見的 wireshark ,

而要使用wireshark ,我們得將 tcpdump 抓到的包資料生成到檔案中,最后再使用 wireshark 打開它即可,

使用 -w 引數后接一個以 .pcap 后綴命令的檔案名,就可以將 tcpdump 抓到的資料保存到檔案中,

$ tcpdump icmp -w icmp.pcap

4.3 從檔案中讀取包資料

使用 -w 是寫入資料到檔案,而使用 -r 是從檔案中讀取資料,

讀取后,我們照樣可以使用上述的過濾器語法進行過濾分析,

$ tcpdump icmp -r all.pcap

4.4 控制詳細內容的輸出

  • -v:產生詳細的輸出. 比如包的TTL,id標識,資料包長度,以及IP包的一些選項,同時它還會打開一些附加的包完整性檢測,比如對IP或ICMP包頭部的校驗和,
  • -vv:產生比-v更詳細的輸出. 比如NFS回應包中的附加域將會被列印, SMB資料包也會被完全解碼,(摘自網路,目前我還未使用過)
  • -vvv:產生比-vv更詳細的輸出,比如 telent 時所使用的SB, SE 選項將會被列印, 如果telnet同時使用的是圖形界面,其相應的圖形選項將會以16進制的方式列印出來(摘自網路,目前我還未使用過)

4.5 控制時間的顯示

  • -t :在每行的輸出中不輸出時間
  • -tt:在每行的輸出中會輸出時間戳
  • -ttt:輸出每兩行列印的時間間隔(以毫秒為單位)
  • -tttt:在每行列印的時間戳之前添加日期的列印(此種選項,輸出的時間最直觀)

4.6 顯示資料包的頭部

  • -x:以16進制的形式列印每個包的頭部資料(但不包括資料鏈路層的頭部)
  • -xx:以16進制的形式列印每個包的頭部資料(包括資料鏈路層的頭部)
  • -X:以16進制和 ASCII碼形式列印出每個包的資料(但不包括連接層的頭部),這在分析一些新協議的資料包很方便,
  • -XX:以16進制和 ASCII碼形式列印出每個包的資料(包括連接層的頭部),這在分析一些新協議的資料包很方便,

4.7 過濾指定網卡的資料包

  • -i:指定要過濾的網卡介面,如果要查看所有網卡,可以 -i any

4.8 過濾特定流向的資料包

  • -Q: 選擇是入方向還是出方向的資料包,可選項有:in, out, inout,也可以使用 --direction=[direction] 這種寫法

4.9 其他常用的一些引數

  • -A:以ASCII碼方式顯示每一個資料包(不顯示鏈路層頭部資訊). 在抓取包含網頁資料的資料包時, 可方便查看資料

  • -l : 基于行的輸出,便于你保存查看,或者交給其它工具分析

  • -q : 簡潔地列印輸出,即列印很少的協議相關資訊, 從而輸出行都比較簡短.

  • -c : 捕獲 count 個包 tcpdump 就退出

  • -s : tcpdump 默認只會截取前 96 位元組的內容,要想截取所有的報文內容,可以使用 -s numbernumber 就是你要截取的報文位元組數,如果是 0 的話,表示截取報文全部內容,

  • -S : 使用絕對序列號,而不是相對序列號

  • -C:file-size,tcpdump 在把原始資料包直接保存到檔案中之前, 檢查此檔案大小是否超過file-size. 如果超過了, 將關閉此檔案,另創一個檔案繼續用于原始資料包的記錄. 新創建的檔案名與-w 選項指定的檔案名一致, 但檔案名后多了一個數字.該數字會從1開始隨著新創建檔案的增多而增加. file-size的單位是百萬位元組(nt: 這里指1,000,000個位元組,并非1,048,576個位元組, 后者是以1024位元組為1k, 1024k位元組為1M計算所得, 即1M=1024 * 1024 = 1,048,576)

  • -F:使用file 檔案作為過濾條件運算式的輸入, 此時命令列上的輸入將被忽略.

4.10 對輸出內容進行控制的引數

  • -D : 顯示所有可用網路介面的串列
  • -e : 每行的列印輸出中將包括資料包的資料鏈路層頭部資訊
  • -E : 揭秘IPSEC資料
  • -L :列出指定網路介面所支持的資料鏈路層的型別后退出
  • -Z:后接用戶名,在抓包時會受到權限的限制,如果以root用戶啟動tcpdump,tcpdump將會有超級用戶權限,
  • -d:列印出易讀的包匹配碼
  • -dd:以C語言的形式列印出包匹配碼.
  • -ddd:以十進制數的形式列印出包匹配碼

5. 過濾規則組合

有編程基礎的同學,對于下面三個邏輯運算子應該不陌生了吧

  • and:所有的條件都需要滿足,也可以表示為 &&
  • or:只要有一個條件滿足就可以,也可以表示為 ||
  • not:取反,也可以使用 !

舉個例子,我想需要抓一個來自10.5.2.3,發往任意主機的3389埠的包

$ tcpdump src 10.5.2.3 and dst port 3389

當你在使用多個過濾器進行組合時,有可能需要用到括號,而括號在 shell 中是特殊符號,因為你需要使用引號將其包含,例子如下:

$ tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'

而在單個過濾器里,常常會判斷一條件是否成立,這時候,就要使用下面兩個符號

  • =:判斷二者相等
  • ==:判斷二者相等
  • !=:判斷二者不相等

當你使用這兩個符號時,tcpdump 還提供了一些關鍵字的介面來方便我們進行判斷,比如

  • if:表示網卡介面名、
  • proc:表示行程名
  • pid:表示行程 id
  • svc:表示 service class
  • dir:表示方向,in 和 out
  • eproc:表示 effective process name
  • epid:表示 effective process ID

比如我現在要過濾來自行程名為 nc 發出的流經 en0 網卡的資料包,或者不流經 en0 的入方向資料包,可以這樣子寫

$ tcpdump "( if=en0 and proc =nc ) || (if != en0 and dir=in)"

6. 特殊過濾規則

5.1 根據 tcpflags 進行過濾

通過上一篇文章,我們知道了 tcp 的首部有一個標志位,

TCP 報文首部

tcpdump 支持我們根據資料包的標志位進行過濾

proto [ expr:size ]
  • proto:可以是熟知的協議之一(如ip,arp,tcp,udp,icmp,ipv6)

  • expr:可以是數值,也可以是一個運算式,表示與指定的協議頭開始處的位元組偏移量,

  • size:是可選的,表示從位元組偏移量開始取的位元組數量,

接下來,我將舉幾個例子,讓人明白它的寫法,不過在那之前,有幾個點需要你明白,這在后面的例子中會用到:

1、tcpflags 可以理解為是一個別名常量,相當于 13,它代表著與指定的協議頭開頭相關的位元組偏移量,也就是標志位,所以 tcp[tcpflags] 等價于 tcp[13] ,對應下圖中的報文位置,

2、tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg 這些同樣可以理解為別名常量,分別代表 1,2,4,8,16,32,64,這些數字是如何計算出來的呢?

以 tcp-syn 為例,你可以參照下面這張圖,計算出來的值 是就是 2

由于數字不好記憶,所以一般使用這樣的“別名常量”表示,

因此當下面這個運算式成立時,就代表這個包是一個 syn 包,

tcp[tcpflags] == tcp-syn

要抓取特定資料包,方法有很多種,

下面以最常見的 syn包為例,演示一下如何用 tcpdump 抓取到 syn 包,而其他的型別的包也是同樣的道理,

據我總結,主要有三種寫法:

1、第一種寫法:使用數字表示偏移量

$ tcpdump -i eth0 "tcp[13] & 2 != 0" 

2、第二種寫法:使用別名常量表示偏移量

$ tcpdump -i eth0 "tcp[tcpflags] & tcp-syn != 0" 

3、第三種寫法:使用混合寫法

$ tcpdump -i eth0 "tcp[tcpflags] & 2 != 0" 

# or

$ tcpdump -i eth0 "tcp[13] & tcp-syn != 0" 

如果我想同時捕獲多種型別的包呢,比如 syn + ack 包

1、第一種寫法

$ tcpdump -i eth0 'tcp[13] == 2 or tcp[13] == 16'

2、第二種寫法

$ tcpdump -i eth0 'tcp[tcpflags] == tcp-syn or tcp[tcpflags] == tcp-ack'

3、第三種寫法

$ tcpdump -i eth0 "tcp[tcpflags] & (tcp-syn|tcp-ack) != 0" 

4、第四種寫法:注意這里是 單個等號,而不是像上面一樣兩個等號,18(syn+ack) = 2(syn) + 16(ack)

$ tcpdump -i eth0 'tcp[13] = 18'

# or

$ tcpdump -i eth0 'tcp[tcpflags] = 18'

tcp 中有 類似 tcp-syn 的別名常量,其他協議也是有的,比如 icmp 協議,可以使用的別名常量有

icmp-echoreply, icmp-unreach, icmp-sourcequench, 
icmp-redirect, icmp-echo, icmp-routeradvert,
icmp-routersolicit, icmp-timx-ceed, icmp-paramprob, 
icmp-tstamp, icmp-tstampreply,icmp-ireq, 
icmp-ireqreply, icmp-maskreq, icmp-maskreply

5.2 基于包大小進行過濾

若你想查看指定大小的資料包,也是可以的

$ tcpdump less 32 
$ tcpdump greater 64 
$ tcpdump <= 128

5.3 根據 mac 地址進行過濾

例子如下,其中 ehost 是記錄在 /etc/ethers 里的 name

$ tcpdump ether host [ehost]
$ tcpdump ether dst	[ehost]
$ tcpdump ether src	[ehost]

5.4 過濾通過指定網關的資料包

$ tcpdump gateway [host]

5.5 過濾廣播/多播資料包

$ tcpdump ether broadcast
$ tcpdump ether multicast

$ tcpdump ip broadcast
$ tcpdump ip multicast

$ tcpdump ip6 multicast

7. 如何抓取到更精準的包?

先給你拋出一個問題:如果我只想抓取 HTTP 的 POST 請求該如何寫呢?

如果只學習了上面的內容,恐怕你還是無法寫法滿足這個抓取需求的過濾器,

在學習之前,我先給出答案,然后再剖析一下,這個過濾器是如何生效的,居然能讓我們對包內的內容進行判斷,

$ tcpdump -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4]'

命令里的可選引數,在前面的內容里已經詳細講過了,這里不再細講,

本節的重點是引號里的內容,看起來很復雜的樣子,

將它逐一分解,我們只要先理解了下面幾種用法,就能明白

  • tcp[n]:表示 tcp 報文里 第 n 個位元組

  • tcp[n:c]:表示 tcp 報文里從第n個位元組開始取 c 個位元組,tcp[12:1] 表示從報文的第12個位元組(因為有第0個位元組,所以這里的12其實表示的是13)開始算起取一個位元組,也就是 8 個bit,查看 tcp 的報文首部結構,可以得知這 8 個bit 其實就是下圖中的紅框圈起來的位置,而在這里我們只要前面 4個bit,也就是實際資料在整個報文首部中的偏移量,

  • &:是位運算里的 and 運算子,比如 0011 & 0010 = 0010

  • >>:是位運算里的右移操作,比如 0111 >> 2 = 0001

  • 0xf0:是 10 進制的 240 的 16 進制表示,但對于位操作來說,10進制和16進制都將毫無意義,我們需要的是二進制,將其轉換成二進制后是:11110000,這個數有什么特點呢?前面個 4bit 全部是 1,后面4個bit全部是0,往后看你就知道這個特點有什么用了,

分解完后,再慢慢合并起來看

1、tcp[12:1] & 0xf0 其實并不直觀,但是我們將它換一種寫法,就好看多了,假設 tcp 報文中的 第12 個位元組是這樣組成的 10110000,那么這個運算式就可以變成 10110110 && 11110000 = 10110000,得到了 10110000 后,再進入下一步,

2、tcp[12:1] & 0xf0) >> 2 :如果你不理解 tcp 報文首部里的資料偏移,請先點擊這個前往我的上一篇文章,搞懂資料偏移的意義,否則我保證你這里會絕對會聽懵了,

tcp[12:1] & 0xf0) >> 2 這個運算式實際是 (tcp[12:1] & 0xf0) >> 4 ) << 2 的簡寫形式,所以要搞懂 tcp[12:1] & 0xf0) >> 2 只要理解了(tcp[12:1] & 0xf0) >> 4 ) << 2 就行了 ,

從上一步我們算出了 tcp[12:1] & 0xf0 的值其實是一個位元組,也就是 8 個bit,但是你再回去看下上面的 tcp 報文首部結構圖,表示資料偏移量的只有 4個bit,也就是說 上面得到的值 10110000,前面 4 位(1011)才是正確的偏移量,那么為了得到 1011,只需要將 10110000 右移4位即可,也就是 tcp[12:1] & 0xf0) >> 4,至此我們是不是已經得出了實際資料的正確位置呢,很遺憾還沒有,前一篇文章里我們講到 Data Offset 的單位是 4個位元組,因為要將 1011 乘以 4才可以,除以4在位運算中相當于左移2位,也就是 <<2,與前面的 >>4 結合起來一起算的話,最終的運算可以簡化為 >>2

至此,我們終于得出了實際資料開始的位置是 tcp[12:1] & 0xf0) >> 2 (單位是位元組),

找到了資料的起點后,可別忘了我們的目的是從資料中打到 HTTP 請求的方法,是 GET 呢 還是 POST ,或者是其他的?

有了上面的經驗,我們自然懂得使用 tcp[((tcp[12:1] & 0xf0) >> 2):4] 從資料開始的位置再取出四個位元組,然后將結果與 GET (注意 GET最后還有個空格)的 16進制寫法(也就是 0x47455420)進行比對,

0x47   -->   71    -->  G
0x45   -->   69    -->  E
0x54   -->   84    -->  T
0x20   -->   32    -->  空格

如果相等,則該運算式為True,tcpdump 認為這就是我們所需要抓的資料包,將其輸出到我們的終端螢屏上,

8. 抓包實戰應用例子

8.1 提取 HTTP 的 User-Agent

從 HTTP 請求頭中提取 HTTP 的 User-Agent:

$ tcpdump -nn -A -s1500 -l | grep "User-Agent:"

通過 egrep 可以同時提取User-Agent 和主機名(或其他頭檔案):

$ tcpdump -nn -A -s1500 -l | egrep -i 'User-Agent:|Host:'

8.2 抓取 HTTP GET 和 POST 請求

抓取 HTTP GET 請求包:

$ tcpdump -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'

# or

$ tcpdump -vvAls0 | grep 'GET'

可以抓取 HTTP POST 請求包:

$ tcpdump -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'

# or 

$ tcpdump -vvAls0 | grep 'POST'

注意:該方法不能保證抓取到 HTTP POST 有效資料流量,因為一個 POST 請求會被分割為多個 TCP 資料包,

8.3 找出發包數最多的 IP

找出一段時間內發包最多的 IP,或者從一堆報文中找出發包最多的 IP,可以使用下面的命令:

$ tcpdump -nnn -t -c 200 | cut -f 1,2,3,4 -d '.' | sort | uniq -c | sort -nr | head -n 20
  • cut -f 1,2,3,4 -d '.' : 以 . 為分隔符,列印出每行的前四列,即 IP 地址,
  • sort | uniq -c : 排序并計數
  • sort -nr : 按照數值大小逆向排序

8.4 抓取 DNS 請求和回應

DNS 的默認埠是 53,因此可以通過埠進行過濾

$ tcpdump -i any -s0 port 53

8.5 切割 pcap 檔案

當抓取大量資料并寫入檔案時,可以自動切割為多個大小相同的檔案,例如,下面的命令表示每 3600 秒創建一個新檔案 capture-(hour).pcap,每個檔案大小不超過 200*1000000 位元組:

$ tcpdump  -w /tmp/capture-%H.pcap -G 3600 -C 200

這些檔案的命名為 capture-{1-24}.pcap,24 小時之后,之前的檔案就會被覆寫,

8.6 提取 HTTP POST 請求中的密碼

從 HTTP POST 請求中提取密碼和主機名:

$ tcpdump -s 0 -A -n -l | egrep -i "POST /|pwd=|passwd=|password=|Host:"

8.7 提取 HTTP 請求的 URL

提取 HTTP 請求的主機名和路徑:

$ tcpdump -s 0 -v -n -l | egrep -i "POST /|GET /|Host:"

8.8 抓取 HTTP 有效資料包

抓取 80 埠的 HTTP 有效資料包,排除 TCP 連接建立程序的資料包(SYN / FIN / ACK):

$ tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

8.9 結合 Wireshark 進行分析

通常 Wireshark(或 tshark)比 tcpdump 更容易分析應用層協議,一般的做法是在遠程服務器上先使用 tcpdump 抓取資料并寫入檔案,然后再將檔案拷貝到本地作業站上用 Wireshark 分析,

還有一種更高效的方法,可以通過 ssh 連接將抓取到的資料實時發送給 Wireshark 進行分析,以 MacOS 系統為例,可以通過 brew cask install wireshark 來安裝,然后通過下面的命令來分析:

$ ssh root@remotesystem 'tcpdump -s0 -c 1000 -nn -w - not port 22' | /Applications/Wireshark.app/Contents/MacOS/Wireshark -k -i -

例如,如果想分析 DNS 協議,可以使用下面的命令:

$ ssh root@remotesystem 'tcpdump -s0 -c 1000 -nn -w - port 53' | /Applications/Wireshark.app/Contents/MacOS/Wireshark -k -i -

抓取到的資料:

-c 選項用來限制抓取資料的大小,如果不限制大小,就只能通過 ctrl-c 來停止抓取,這樣一來不僅關閉了 tcpdump,也關閉了 wireshark,

到這里,我已經將我所知道的 tcpdump 的用法全部說了一遍,如果你有認真地看完本文,相信會有不小的識訓,掌握一個上手的抓包工具,對于以后我們學習網路、分析網路協議、以及定位網路問題,會很有幫助,而 tcpdump 是我推薦的一個抓包工具,

9. 參考文章

  1. FreeBSD Manual Pages About tcpdump
  2. Linux tcpdump命令詳解
  3. 一份快速實用的 tcpdump 命令參考手冊
  4. 超詳細的網路抓包神器 tcpdump 使用指南
  5. [譯]tcpdump 示例教程
  6. [英]tcpdump 示例教程

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/44952.html

標籤:Linux

上一篇:如何在Vim中更改顏色和主題

下一篇:運維太忙?那是你還沒掌握 Ansible !

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more