Wiresharkは言わずと知れたパケット解析ツールです。
以前は Etherealと呼ばれていたようです。2006年にWiresharkに名前が変わり, v1.0が2008年にリリースされています。
最近, 世間を騒がせたIMEが自動で入力データを送信するということも Wiresharkならわかります。
また, ストリーミング配信機能を開発する場合などパケットレベルでのデバッグに重宝します。
どのように Wiresharkがパケットをキャプチャしているかという所からみていきます。
NICの仕組み
NICは Ethernet規格 (IEEE802.3シリーズ)である 1000BASE-T等でデータの入出力を行うモジュールです。
補足ですが無線LAN規格は IEEE802.11で定義されています。
基本構成は以下の図の通りです。
・PHY(ネットワークインターフェイス)
受信時は高周波ノイズフィルタ, ADC, 4B5Bデコーダを経由してイーサネットコントローラーに出力します。
送信時はイーサネットコントローラーで受けたデータをMLT-3に変換しケーブルに転送します。
・MAC
MACフレームの送受信を行います。MAUというバッファ領域を持ちます。CSMA/CDでアクセス制御しているのがこの部分です。
・HOST I/F (バスインターフェイス)
CPUとNIC間でデータの転送を行います。データ転送方式には、I/O方式、DMA方式、USB方式などがあります。DMAの場合はNIC自体ではバッファ管理をしません。
Wiresharkに表示されるまで
NICがLANケーブルなどから送られてきた電気信号をデジタル信号としてフレーム化します。
この時点の情報をキャプチャドライバ(LibPCap)が取得・解析してwiresharkが画面に表示します。
しかし, 厳密には表示されているのはNICに来た時点のパケットではないです。
例えばLinuxの場合以下の順序でプログラムはパケットを認識します。
- NICがパケットを受信
- NICドライバの割り込みハンドラの起動
- 受信パケットの処理をカーネル上位に依頼
- pollハンドラによってパケット受信処理
割り込みハンドラで直接, パケットを処理しないのは割り込み処理時間をできるだけ短くするためです。
また, pollで読み出すのは NICでなく DMAバッファに転送済みのパケットになります。
Wiresharkのインストール
Windows / mac はここからDLしてインストールします。
debian系またはcentosなら以下です。
$ sudo apt-get install wireshark
$ sudo yum install wireshark
フィルタ機能
ここからはWiresharkの機能について説明します。
必要なパケットだけ表示させたい場合にフィルタ機能を使います。
- tcp //指定したプロトコルだけ表示
- !tcp //指定したプロトコルだけ非表示
- tcp.port == xxx //指定したTCPポートだけ表示
- ip.addr == xxx //指定したIPだけ表示
- eth.addr == xxx //指定したMACだけ表示
Applyで適用します。Wiresharkが重くなるので必要なタイミングでstart/stopも使うと良いです。
Proxyからの8080portのパケットをHTTPで表示させたい場合です。
まずは tcp.port == 8080でフィルタリングします。
フィルタリングされたパケットに対して[Decode As]を選択します。
- 1. Transportタブを選択
- 2. portを選択
- 3. プロトコルをHTTPに設定
分析機能
通信フローのグラフ表示:
Statistics -> Flow Graphs に設定します。
TCPストリームの確認:
TCPソケットのデータをまとめて確認(レスポンスとレスポンスの対応関係)したい場合は,Analyze → Follw TCP Stream に設定します。
TCPパケットを分析する上で知っておくべきこと
輻輳制御、ウィンドウサイズなど覚えることは多いですが、まずコネクション型プロトコルとして接続開始時のTCP3ウェイハンドシェイクは知っておきたいところです。
[1] C -> S
SYNセグメントの送信。
SYN番号0がセットされます。
[2] S -> C
SYN-ACKセグメントの送信します。
SYN番号0、ACK番号1がセットされます。
[3] C -> S
ACKセグメントの送信。
SYN番号1、ACK番号1がセットされます。
接続終了時には終了要求時にFIN-ACK, 応答としてACKが送られます。
細かい部分は RFC793で確認できます。
HTTPパケットを分析する上で知っておくべきこと
HTTPは接続先(クライアント)の状態を管理しないという意味でセッションレス/ステートレスのプロトコルです。
HTTPリクエスト:
リクエストライン, ヘッダ(要求ヘッダ/エンティティヘッダ), メッセージ(POSTデータ)から構成されます。
HTTPレスポンス:
レスポンスライン、ヘッダ(応答ヘッダ/エンティティヘッダ), メッセージ(HTML/画像etc)から構成されます。
よく使われるHTTPメソッドとしてGETとPOSTがありますが、
GETがURIでデータ送信 (最大256Byte)するのに対して, POSTはメッセージボディでデータ送信 (基本無制限)するという違いがあります。
HTTPレスポンスに含まれるHTTPステータスコードは大きく以下に分類されます。
- 100: 通知
- 200: 成功
- 300: リダイレクト
- 400: クライアントエラー
- 500: サーバエラー
細かい部分はRFC2068で確認しましょう。HTTPとWiresharkの関連記事はこちらです。
HTTPS通信(SSL/TLS)の復号
WiresharkにはopenSSLサーバなどHTTPS関係の開発をしているときのためにSSL/TLSを解析するための機能があります。
TLSはトランスポート層のプロトコルでTCPのラップ機能ですのでHTTP通信の前のセッションで使われます。
[Edit]->[Preferences]-> [Protocols]-> [SSL] にpemファイルを登録することで解析できます。
他にもWiresharkを使えば, GETで取得したJPEG画像のバイナリデータを引っ張ってきてバイナリエディタでファイルの先頭と終端のマーカであるFFD8からFFD9までのデータを保存し, 画像ビューアで確認するといった使い方もできます。