由於圖片和格式解析問題,可前往 閲讀原文
到這裏已經講了兩個抓包工具的使用了,大家應該對抓包不是很陌生了。而wireshark相對於fiddler和charles更加偏向於網絡層面的抓包或者説是一個網絡封包分析工具。使用對象更適合於網絡相關人員(網絡管理員/相關運維等等),目的用來截取網絡通信,顯示詳細的封包資料。
wireshark可以用來檢測網絡環境、入侵偵測系統等網絡層面的用處,相對於開發人員,可以用來分析一些基礎的網絡層面的基礎,如HTTP協議、UDP協議、TCP/IP協議、ARP協議等對我們比較友好的網絡協議,當然如果你熟練操作網絡可以沒有任何限制。
下載安裝
:::tip
由於一些歷史原因,wireshark已經是個免費軟件,下載簡單,功能強大,非常適合網絡協議的學習和認識
:::
wireshark支持windows、macOS、Linux幾個版本,基本上常見的操作系統都可以支持的,直接打開官網下載頁面,選擇適合自己的操作系統,下載即可,下載完後一路點擊確定安裝就可。這裏作者是macOS,就安裝了mac版,如無特殊備註,以下都以mac版本為基礎介紹,其他大同小異。
下載後打開大概長這個樣子,它可以捕獲機器上所有物理網卡虛擬網卡的流量,選擇一個網卡開始捕獲
菜單欄
菜單欄這裏只講下統計,它相對來説更加實用。統計內部有好多不同維度的分組,可以從不同維度去查看統計信息,如:流量、TCP流、UDP多播、HTTP等等。統計需要數據才可以統計出結果,可以先抓取少量的包,點擊內部的流量圖可以很清晰的看到網絡通信
工具欄
當進來時會進入歡迎頁面,可以選擇指定的網絡接口(本地、wifi)或直接點擊左上角的鯊魚圖標開始抓包。
以上看到已經抓取了大量的網絡數據包,下面開看看工具欄的作用
工具欄主要使用來控制抓包的,以上的圖標按順序依次是開始抓包、停止抓包、重新捕獲、捕獲選項(網卡、過濾器)、打開本地捕獲文件、保存捕獲文件、關閉捕獲、重新加載捕獲文件、搜索(過濾器),基本上的圖標控制按鈕就這麼簡單,後面的都是對界面的一些控制,沒什麼説的,自己動手試試即可。
過濾器
當使用wireshark抓包時難免會有大量的抓包記錄,而我們往往會針對某個網絡包進行分析,而在這種大量數據下會嚴重影響到分析進度。為了避免其它數據造成的干擾,wireshark提供了過濾器來幫助過濾掉不必要的數據或只顯示我們想要的數據。
過濾器分為<u>捕獲過濾器</u>和<u>顯示過濾器</u>,而捕獲過濾器又可以對<u>網絡接口</u>和<u>協議相關</u>的兩個維度的過濾。顯示過濾器主要是對抓取到的網絡數據包進行過濾顯示,其針對的顯示方面的的過濾,而捕獲過濾器則是從源頭進行過濾。網絡接口主要告訴wireshark要抓取哪個接口的網絡數據包如:wifi、本地迴環、以太網、虛擬網、藍牙等等,協議方面的選項通常告訴其抓取什麼協議、什麼端口、ip等等,如:TCP協議、HTTP協議、廣播、ip等等。
在進入wireshark時的歡迎頁面就可以對進行不同的接口進行選擇,雙擊接口就可以抓取了,不需要選擇時,默認會抓取所有接口的數據,可以直接點擊左上角的鯊魚按鈕開始抓取。
除了在歡迎頁選擇不同的網絡接口外,也可以在抓包頁面上方的類似設置的按鈕中,也可以選擇不同的接口和詳細的抓包選項,如下圖:
更詳細過濾一些選項
上面的過濾器我選擇了<u>抓取本地接口和端口為9999</u>的數據包,這裏我用Nodejs監聽9999端口號開啓了一個web服務,接着用curl請求這個地址:
➜ curl -I 192.168.3.2:9999 # 請求成功
HTTP/1.1 200 OK
X-Powered-By: Express
Set-Cookie: __ut=123456; Path=/
Content-Type: application/json; charset=utf-8
Content-Length: 79
ETag: W/"4f-IdYGYravFqZ+6sBfe27/eQDuPDo"
Date: Sat, 22 Oct 2022 08:46:19 GMT
Connection: keep-alive
Keep-Alive: timeout=5
現在看看當前的抓包情況,可以看到已經抓取到了,原地址和目標地址都是192.168.3.2本機局域網地址,還看到TCP協議、HTTP協議,如果現在只想分析HTTP協議的數據包呢,就可以用上顯示過濾器了。設置它很簡單,在記錄上方的輸入框即可過濾。如下圖:顯示http協議的請求。
以上還可以再細分,可以結合多個過濾選項使用and/or進行連接過濾,如http請求的攜帶了query
http and http and http.request.uri.query.parameter
這裏過濾選項不需要記下來,點擊輸入框前面的小圖標,可以列出不同的選項,點擊後可以在輸入框中添加.進行屬性的進一步過濾。除了這個內置的顯示過濾外,可以點擊菜單欄的放大鏡按鈕,也會顯示出過濾的輸入框。這裏相對來説有了更廣的過濾條件,可以使用顯示過濾、正則搜索、十六進制、字符串等等,點擊搜索即可,搜索後並不會將不在範圍的記錄隱藏掉,而知識將目標高亮而已。
ARP協議
通過前面的學習你應該對wireshark這款軟件的抓包基本功能有了瞭解,現在就來使用它來抓取數據包分析吧,本文會分別介紹ARP協議、TCP協議等網絡協議,讓我們以ARP協議開始吧。
在抓包開始前首先要明白什麼是ARP協議,瞭解協議本身有助於我們抓取的準備和方向,這裏簡單的概述下。
ARP是地址解析協議,從協議層次角度是個網絡層協議,功能角度是鏈路層協議,用來查詢ip所對應的mac地址。在互聯網通信中,主機與主機之間通信,都是通過OSI模型從上到下的協議將數據封裝最終發送到目的主機,通常情況下我們常見的是對應主機的ip,然後就可以知道目標主機的位置了,但這只是表面上的,通信雙方還需要知道雙方的mac地址才能通信,沒有mac地址就像快遞只寫了收件人姓名,卻沒有收件地址一樣。
上層應用程序只關心ip地址而不關係mac地址,<u>mac地址需要通過ARP協議獲取目標主機地址</u>,完成數據的封裝。那麼ARP協議是如何獲取目標主機的mac地址的,假如這裏有兩台機器:p1的ip地址192.168.3.1,p2的ip地址192.168.3.2,當p1想和p2通信時,從OSI協議封裝順序發送方自頂向下封裝數據,ARP從上層知道了p2的目標ip地址,然後封裝ARP數據包,將自己的ip地址和mac地址和對方的ip和mac佔位地址封裝,然後通過以太網的<u>廣播</u>形式發送出去,交換機、網關或路由器等設備接收到廣播包後,會將數據發給同一局域網的其他主機,當不同的主機接受到廣播包後,會判斷自己是不是這個發送者尋找的ip,如果不是則會將包丟棄掉不做任何應答;而如果當前主機和目的ip一致的話,將會接受此包並將自己的mac地址封裝進去,並以單播的形式迴應發送主機方,發送主機方就會知道目標ip所對應的mac地址了;如果在局域網中沒找到響應的主機,交換機等會繼續向上發送數據包直到找到位置。
上圖簡單的畫了請求的過程:
- 發送方ARP廣播發送數據包請求到交換機
- 交換機轉發給局域網內的主機
- 不是目標ip的主機丟棄掉數據包,目標ip主機接收數據包
- 目標主機以單播的形式迴應發送方
:::tip 小提示
在ARP請求廣播過程中,途徑的網關和其他接收到廣播的主機雖然不是目標主機,但也會在自己的ARP緩存表中記住發送方的ip和mac地址,這是方便以後其他主機向目標主機通信。
當目標主機找到後,也會記住發送方的ip和mac地址,然後將自己的mac地址和ip地址封裝數據後以單播的形式迴應發送給發送方。
:::
接下來就用wireshark抓包看看實際的網絡請求情況,這裏一台機器的ip為192.168.3.8,現在讓它請求網關192.168.3.1,這裏使用linux的nmap掃描工具掃描網關。
首先先打開wireshark監聽抓包,這裏直接抓取所有的接口,在顯示過濾器中輸入ARP協議來過濾顯示ARP協議的數據包。
nmap 192.168.3.1 # 然後會找到以下信息
# Starting Nmap 7.70 ( https://nmap.org ) at 2022-10-22 22:02 CST
# Nmap scan report for 192.168.3.1
# Host is up (0.0070s latency).
# Not shown: 972 closed ports
# PORT STATE SERVICE
# 3/tcp filtered compressnet
# 53/tcp open domain
# 80/tcp open http
# ....
arp -a # 查看ARP緩存表信息
# ➜ arp -a
# _gateway (192.168.3.1) at dc:33:xx:xx:xx:07 [ether] on enp0s5 # 這裏就是網關被找到了
# ? (192.168.3.2) at 38:f9:xx:xx:05:db [ether] on enp0s5
上面通過掃描工具掃描網關,再查看ARP緩存表中已經緩存了網關信息,接下來看看抓包情況:
ARP請求:
ARP應答:
從抓包數據可以看到,首先Apple(192.168.3.8)主機以廣播的形式發送數據包,ARP請求數據包中有自己的Send MAC address、ip address還有目標主機的ip192.168.3.1和mac地址00:00:00:00:00:00(這裏0表示坑位待目標填寫),攜帶信息Who has 192.168.3.1? tell 192.168.3.8。當Huawei(網關192.168.3.1)接受到Apple發送來的數據包後,將自己的mac地址封裝僅需其他的保持不變,再以單播的形式發送ARP Reply數據包,攜帶信息192.168.3.1 at xx:xx:xx:xxx,這樣在Apple接收到數據包後就知道了目標的Mac地址了,就可以進行數據發送了。
這裏簡單説下ARP數據包中一些字段:
- Hardware type:硬件類型(標識鏈路層協議)
- Protocol type:協議類型(標識網絡層協議)
- Hardware size:硬件地址大小(標識mac地址長度),這裏是6字節,48bit
- Protocol size:協議地址大小(表示ip地址長度),這裏是4字節,32bit
- Opcode:操作碼(表示ARP請求類型),1表示請求,2表示應答
- Sender Mac address:發送者mac地址
- Sender IP address:發送者ip地址
- Target MAC address:目標mac地址
- Target IP address:目標ip地址
以上便是ARP協議的基本原理,通過nmap掃描工具,再用wireshark進行抓包分析後應該已經對ARP協議不陌生了,基本就是<u>一問一答</u>簡單形式。當然這裏主要還是講wireshark怎麼抓取ARP數據包,來理解ARP的簡單概念,至於ARP的更詳細的概念可以看看其他文章,如果沒有後面也會更新相關文章。
TCP協議
TCP協議是基於字節流面向連接、可靠的、全雙工的單播協議,在通信前必須建立連接,也就是常説的三次握手,然後會斷開進行四次揮手。我們來先了解下TCP頭部。
- 源端口、目標端口:TCP裏沒有源IP和目的IP,這是IP層協議的事情,源IP、源端口、目標IP、目標端口構成了TCP
四元組,一個四元組可以標識一個連接。 - 序列號:用於確認包的的順序,序列號加上報文長度,用於確定傳輸的是哪一段數據。
- 確認號:TCP使用確認號來告知對方下一個期望接受的序列號
-
標誌位:用來發起連接同步初始序列號,有些用來確認數據包,還有用來結束連接的
- SYN:用於發起連接數據包同步初始序列號
- ACK:確認數據,只有當ACK=1時有效
- RST:強制斷開連接
- FIN:告知對方數據發送完畢,準備斷開連接
- PSH:告知對方數據包收到後馬上交給應用層,不能緩存
- 窗口大小:用來控制對方發送的數據量
更多TCP的詳細內容請查看我的「TCP協議」一文
上面簡單的介紹了TCP頭部部分信息,TCP的連接由發送SYN開始,結束時通過FIN斷開連接。下面我們就通過wireshark進行抓包分析。因為HTTP請求也是基於TCP協議的,這裏以HTTP請求為例展開三次握手和四次揮手的細節。
這裏開啓一個node服務作為web服務器:
const express = require("express")
const app = express()
const port = process.env.PORT || 9999
app.use(async (req, res, next) => {
res.setHeader("connection", "close")
res.json({
url: req.url,
...req.headers,
...req.query
})
})
app.listen(port, () => {
console.log(`Server is running on port ${port}`)
});
wireshark我們選擇本地迴環地址網卡接口,端口選擇9999
三次握手
這裏使用curl發起服務請求
➜ curl http://localhost:9999
{"url":"/","host":"localhost:9999","user-agent":"curl/7.64.1","accept":"*/*"}%
看下抓包情況:
從上圖抓包記錄可以將記錄分為三部分:①TCP三次握手連接,②HTTP請求相關,③TCP四次揮手
下面這張圖概況了三次握手的摘要
抓包記錄:
- 這裏看出兩端通信的端口為
54987(終端)和9999(服務器),終端發送SYN類型請求,指明客户端的初始化序號為0,這裏的0位相對值,其真實性值為3059428279,並告訴下次的序列號為1,如下圖:
- 服務端接收到客户端的SYN數據包後,發送自己的應答SYN包,並指定自己的序列號0(真實值3338838224),並將
客户端的序列號+1發送ACK=1確認包(acknumber=3059428280),並告訴下次序列號為1,如下圖:
- 客户端接收到了服務端的SYN數據包和ACK包後,也將服務端的SYN+1(acknumber = 3338838225)作為ACK數據包發送給服務端,就完成了三次握手
至於ACK值不斷加1是為了標識數據包保證接收方的順序性,因為發送時數據可能亂序,在收到數據後,TCP不會直接把數據交給上層,而會做一個緩存,直到傳輸完畢將包按順序組裝在上交給應用層。
三次握手的簡單理解:
第一次:客户端發送數據到服務端,服務端接收到後知道客户端的發送能力沒問題
第二次:服務端發送數據到客户端,客户端接接收後知道服務端的接收能力正常,發送能力也沒問題
第三次:客户端再發送數據到服務端,服務端接收後知道客户端的接收能力沒問題
通過三次握手兩端都知道了對方發送和接收沒有問題,之後就可以正常通信了。
四次揮手
當客户端請求畢後就會斷開連接,由於為了提高傳輸效率http使用keep-alive會在一定時間內保持TCP的連接,這裏設置HTTP頭部connection=close表示請求完畢後立即斷開連接。
來看回收抓包記錄:
- 在客户端請求完畢後會發送FIN報文給服務端,包含自己的序列號seq=79和ack=125來確認對方最近一次發送的數據,然後表示我沒有其他請求了,這時客户端進入
FIN_WAIT1狀態
- 服務端接收到數據包後,發送包含自己的seq=125和ack=80的ACK報文給客户端,表示我知道了,並通知上層應用另一端發起了關閉操作,此時服務端並不會立馬發起關閉操作,也就是發送服務端的FIN報文,此時服務端進入
CLOSE_WAIT狀態,客户端進入FIN_WAIT2狀態
- 等一會時間服務端再發送包含seq=125,ack=80的FIN報文和ACK報文並期待下一次的ACK序列號為126,表示可以斷開連接了,服務端進入
LAST_ACK狀態
- 客户端接收到後會在發送ack=126的ACK報文,最後斷開連接,此時客户端進入
TIMED_WAIT狀態,服務端將會進入CLOSED狀態,最後再等2MSL(Maximum Segment Lifetime)客户端也進入CLOSED狀態
通過上面的分析已經對四次揮手有了更深理解了,下面再畫個圖總結下
以上就是TCP揮手的基本原理了。這裏解釋一下兩個問題:
- 為什麼揮手要四次,而握手是3次?
因為握手時服務端直接確認連接不需要等待,所以發送SYN+ACK數據包。而揮手時服務端接受到了客户端的FIN包後,知道客户端沒有請求了但還可以繼續接受數據包,服務端也並不能立馬關閉連接,因為服務端此時可能數據並沒有發送完畢,需要等待發送完畢後才會主動發送FIN包請求斷開。 - 為什麼客户端揮手後發送了
ACK包還要等2MSL段時間才會進入CLOSED狀態?
這是因為當客户端發送了ACK報文後,有可能有丟失的包的可能,這導致服務端還沒有收到客户端的ACK報文,會認為自己發的FIN報文可能客户端沒有收到,於是會再發一個給客户端,客户端會再發送ACK報文,重新計時2MSL,等服務端接收到ACK報文後,則不會再發送FIN報文,2MSL時間段後客户端正式進入CLOSED狀態。
HTTP協議
由於HTTP協議是基於TCP協議的,所以上面我們用curl發起的是HTTP請求,那我們看下http請求過程。
- 首先客户端發送GET請求給服務端
- 服務端發送TCP的ACK的數據包確認已經收到請求了
- 服務端發送http響應,狀態碼200
- 客户端接收到後,發送TCP的ACK數據包表示已經接收到了數據
我們通過跟蹤HTTP數據流看下細節:
到這裏已經瞭解瞭如何用wireshark分析ARP協議、TCP協議和HTTP協議了,當然這只是簡單的講解,其他協議都大同小異,更多功能自己可以動手試試。
統計
統計可以對網絡數據進行不同維度的統計,如:HTTP、TCP、UDP、DNS等相關的統計,這些統計比較簡單,自己動手試試就會明白。
小結
本篇介紹了wireshark的基本使用,並通過對ARP協議、TCP協議和HTTP協議的分析,已經掌握了分析數據包的基本能力,並加強了相關協議的理解,其他相關的協議都大同小異。到本篇已經講了3款抓包軟件了,相信大家對抓包已經不陌生了,希望通過這些抓包工具可以提高你的分析能力和對原理的認識。
由於圖片和格式解析問題,可前往 閲讀原文