第 2 章介紹過 Wireshark,但只談到擷取,沒談分析。Wireshark 功能極其龐大,這裡只會觸及與協定分析最直接相關的那一小部分。

設定擷取介面與過濾器#

圖表 5-1:Windows 上的 Wireshark 主視窗

啟動 Wireshark 後,主視窗會讓你選擇要從哪個網路介面擷取流量。為了只抓到我們想分析的流量,先從選單選擇 Capture ▸ Options 開啟選項對話框,然後做兩件事:

圖表 5-2:Wireshark 的 Capture Interfaces 對話框

  • 選擇網路介面。範例中在 Windows 上選的是 Local Area Connection(主要的乙太網路連線),因為 Localhost 不容易擷取。
  • 設定擷取過濾器(capture filter)。例如填入 ip host 192.168.10.102,把擷取範圍限制在往返該 IP 位址的流量。這個 IP 是聊天伺服器的位址,請依你的環境調整。

按下 Start 開始擷取。

擷取過濾器與顯示過濾器(display filter)是兩回事:擷取過濾器決定「什麼會被寫進擷取檔」,一旦漏掉就補不回來;顯示過濾器只是把已擷取的內容篩出來看。分析初期寧可放寬擷取過濾器,之後再用顯示過濾器收斂。

產生流量並擷取封包#

封包分析的核心策略是:盡可能從目標應用程式產生各式各樣的流量,藉此提高撞見各種協定結構的機率。書中示範的做法是跑三個 ChatClient 工作階段——alice 一段、bob 兩段。

三個範例工作階段的完整操作紀錄

> 表示在 ChatClient 中輸入的指令,< 表示伺服器回應並寫到主控台的內容。

alice 的工作階段:

# alice - Session
> Hello There!
< bob: I've just joined from borax
< bob: How are you?
< bob: This is nice isn't it?
< bob: Woo
< Server: 'bob' has quit, they said 'I'm going away now!'
< bob: I've just joined from borax
< bob: Back again for another round.
< Server: 'bob' has quit, they said 'Nope!'
> /quit
< Server: Don't let the door hit you on the way out!

bob 的第一個工作階段:

# bob - Session 1
> How are you?
> This is nice isn't it?
> /list
< User List
< alice - borax
> /msg alice Woo
> /quit
< Server: Don't let the door hit you on the way out!

bob 的第二個工作階段:

# bob - Session 2
> Back again for another round.
> /quit Nope!
< Server: Don't let the door hit you on the way out!

之所以特別讓 bob 跑兩個工作階段,是為了捕捉那些只在連線建立與中斷之際才會出現的事件。只跑一次連線,你永遠看不到「某人離線」這類通知封包長什麼樣子。

跑完這些工作階段後,按下 Stop 停止擷取,並把封包存檔備用。

圖表 5-3:Wireshark 中擷取到的流量

基本分析:先看對話全貌#

要對擷取期間發生了什麼事有個概觀,可從 Statistics 選單下手。選擇 Statistics ▸ Conversations,會開啟一個視窗,列出高階的對話(例如 TCP 工作階段)。

圖表 5-4:Wireshark 的 Conversations 視窗

在我們的擷取結果中,可以看到三個獨立的 TCP 對話,而且它們都來自連接埠 12345——這正好對應到我們跑的三個用戶端工作階段。

「先統計、後鑽研」是個好習慣。在還沒看懂任何一個位元組之前,Conversations 視窗就已經告訴你:有幾條連線、誰跟誰講話、資料量多大。這些是後續推論的骨架。

讀取 TCP 工作階段的內容#

在 Conversations 視窗中選取其中一個對話,按下 Follow Stream 按鈕,就會開啟新視窗,以 ASCII 文字顯示整條串流的內容。

圖表 5-5:在 Wireshark 的 Follow TCP Stream 檢視中顯示 TCP 工作階段內容

從這個畫面可以立刻得到兩個結論:

  • 大量資料是明文傳送的。Wireshark 會把無法以 ASCII 表示的資料換成一個點(.),但即使如此,可讀文字仍然清晰可見。
  • 但這不是純文字協定。控制資訊全是不可列印字元;我們看得到文字,純粹是因為 SuperFunkyChat 的主要用途就是傳送文字訊息。

Wireshark 用顏色區分方向:粉紅色代表出站(outbound)藍色代表入站(inbound)。在 TCP 工作階段中,出站是指從發起連線的用戶端送出的流量,入站則來自 TCP 伺服器。

由於我們擷取了往返伺服器的全部流量,可以修改視窗中的 Stream 編號(例如改成 1)來切換到另一條對話。比對不同工作階段會發現:某個用戶端送出的文字(例如 “How are you?"),會在另一個工作階段中以伺服器送達的形式出現。

圖表 5-6:來自另一個用戶端的第二個 TCP 工作階段

這種「同一段文字在兩條串流中分別以送出與收到的形式出現」的交叉比對,是釐清協定語意最省力的線索之一。接下來要處理的,就是文字之間那些二進位的部分到底代表什麼。