Capturing Application Traffic
分析をする上で有用なトラフィックを捉えることが最初の関門となるだろう. ここでは,パッシブ,アクティブの2種類のキャプチャ手法を説明する.
パッシブキャプチャ
トラフィックに影響を与えず,通信路からデータを抽出する.(Wireshark) また,様々なアプリケーションがトラフィックをリダイレクトする機構を提供している.
アクティブキャプチャ
クライアント,サーバー間のトラフィックを妨げてデータを抽出する.(プロキシ, 中間者攻撃)
Passive Network Traffic Capture
通常,特別なハードウェアを必要とせず,独自のコードを作成する必要もなく比較的容易な手法である. 下図はクライアントとサーバーがイーサネット経由でネットワーク通信するシナリオである. パッシブキャプチャは,クライアントホスト,サーバーホスト,通信路上のタップデバイスのいずれかで直接探知可能.
Quick Primer for Wireshark
Wiresharkは一般的なパケットスニッフィングアプリケーションである.(5章で詳細なフィルタ作成を扱う) イーサネットインターフェイスからトラフィックキャプチャするには,キャプチャデバイスモードをプロミスキャス(無差別)モードにする必要がある. プロミスキャスモードは自分宛のフレーム以外もキャプチャする. 自分のアプリケーションの監視ならインターフェイスにループバックインターフェイス,送信インターフェイスを指定すれば良い. その他の場合は,ハブや設定を仕込んだスイッチなどのハードウェアを使う必要がある.
上図はwiresharkのデフォルトの表示である. 1がキャプチャされた生パケットのタイムライン. 2が個別のプロトコルレイヤー毎の詳細な情報. 3がパケットの生データ. ネットワークの性質上,パケットが順序通りに到着するとは限らないため,タイムライン上の表示が順序通りに整っているとは限らないが,TCPはプロトコル上,順序を整える仕組みを持つためTCP解析すると下図のような順序通りの情報が得られる. Wiresharkに関するこれ以上の情報は「実践パケット解析」を参照.
Alternative Passive Capture Techniques
キャプチャ権限のない場合,スニファを使うのが適切でない場合がある. 特定のアプリケーションのトラフィック確認をパケットスニッフィングツールを用いずにトラフィックを抽出する.
System Call Tracing
OSは2つの実行モードをサポートする. カーネルモードは高レベル権限で動作し,OSのコア機能を実現するコードが含まれる. ユーザモードは低レベル権限で動作し,通常のプロセスが実行される場所である. カーネルはシステムコールをエクスポートすることでユーザプロセスにサービスを提供し,ユーザにファイルアクセスや作成の機能を提供する. アプリケーションがサーバーに接続するときシステムコールを用いる. Unix系システムはネットワーク通信用のBerkeley Socketsモデルのようなシステムコールを実装している. IPプロトコルはもともとBerkeley Software Distribution 4.2で実装されており,これが標準となった.
| システムコール名 | 説明 |
|---|---|
| socket | 新規ソケットファイル識別子を作成 |
| connect | IP/ポートで指定したソケットと接続 |
| bind | 自ソケットのIP/ポートを固定 |
| recv, read, recvfrom |
ソケットを通しデータを受信.readはファイルディスクリプタをからデータを読み取る汎用機能.recv, recvfromはsocket API専用の受信機能 |
| send, write, sendto |
ソケットを通しデータを送信 |
The strace Utility on Linux
Linuxでは,アプリケーションが特権ユーザとして実行されていない限り,特権なしでユーザプログラムのシステムコール監視が可能である. 下図はシステムコール監視ユーティリティであるstraceの出力である.
- ハンドル3が割り当てられた新規TCPソケットを作成.
- ポート5555.IPアドレス192.168.10.1に対してTCP接続を確立.
- “Hello World!”を送信.
- “Boo!”を受信.
Monitoring Network Connections with DTrace
Dtraceはトレースポイントを有効にすることでシステム全体の監視ができる. Dtraceはスクリプトによって構成する. 下図のスクリプトはconnectシステムコールを監視し,IPv4接続を出力する. connectシステムコールはDTrace言語のarg0, arg1, arg2の3引数をとる. arg0はソケット識別子,arg1はアドレス構造体,arg2はアドレスの長さ.
- sockaddr_in構造体はIPv4接続で使われるアドレス構造体である.
- 監視ポイントを指定(‘dtrace -l’ で監視ポイント一覧を取得可能)
- フィルタを指定(アドレス構造体の大きさでIPv4と判断)
- 検査しやすいようにローカル構造体にコピー
- プロセス名,宛先IPアドレス,ポート番号を表示
これを実行するにはtraceconnect.dにコピーしたのちrootユーザとして’dtrace -s traceconnect.d’を実行. その後,ネットワーク接続アプリケーションを使用すると,下図のような出力が得られる. OSXなどではSystem Integrity Protextionによりシステムコールトレースが制限される dtrussでgolangのシステムコールをトレースしたい - Qiita
Process Monitor on Windows
Windowsの場合,直接システムコールを呼び出さずにネットワーク機能をつかう. つまり,ネットワークスタックはドライバを介して公開され,接続の確立はドライバのオープン,読み取り,書き込みシステムコールでソケットを設定する. Vista以降はアプリケーションがネットワークを監視できるようにイベント生成フレームワークをサポートしている. これを自分で用いるのは複雑であるが,利用するツール(Process Monitor)が存在する. 下図はネットワーク接続イベントのみをフィルタリングする場合のインターフェイスである.
ツールバーのフィルタを選択すると監視対象プロセスからのイベントのみを表示できる. Process Monitorは,トラフィックの呼び出し元スタックの状態をキャプチャ可能であり,リバースエンジニアリングによってネットワークプロトコルを作成(6章)するときに重要である. 下図はリモートサーバーへのHTTP接続の詳細をフィルタしたものである.
- プロセス名
- 操作
- アドレス
- イベントの詳細
これは他のツールほど効果的ではないが,特定のアプリケーションが利用しているプロトコルを特定する場合に便利である. 特定したのち,アクティブなトラフィックキャプチャを通して情報を詳細に分析する.
Advantages and Disadvantages of Passive Capture
Advantages
- クライアント, サーバの通信が中断されないこと
- トラフィックのsrc, dstアドレスが変更されない
- アプリケーションの変更, 再設定が不要
パッシブキャプチャはクライアント,サーバーを直接制御できない場合の唯一のトラフィックキャプチャ手法になりうる. 通常はパッシブでトラフィックを監視し,分析対象アプリケーションを見つけたのちアクティブキャプチャでプロトコル分析する.
Disadvantages
- 低レベルのためトラフィックの解釈が困難な場合がある
暗号化されたプロトコルの復号,圧縮の無効化,悪用のためのトラフィックの変更のためにトラフィックを操作するとこが困難な場合もあるため,そのような場合はアクティブキャプチャを用いる.
Active Network Traffic Capture
アクティブキャプチャは中間者攻撃を用いてトラフィックに影響を与える. キャプチャデバイスはクライアントとサーバーの間にありブリッジとして機能する. これにはプロトコル分析や悪用が容易という利点がある
- トラフィックの変更
- 暗号化や圧縮機能の無効化
ブリッジするため,パッシブよりも難しく,意図しない影響を与えることがある. サーバーかクライアントのアドレスをプロキシに変更すると,混乱を招きアプリケーションが誤った場所に送信することがある.
Network Proxies
中間者攻撃の一般的な方法はアプリケーションにプロキシサービスを介して通信を強制することである. 本節では以下を説明する.
- キャプチャ,分析,プロトコルの活用に利用可能なプロキシタイプの長所と短所
- クライアントからプロキシにトラフィックを送信する方法
各プロキシの比較
- Port-Forwarding Proxy
プロキシサーバーをセットアップして,クライアントからの接続を待つ. 接続要求があると,プロキシとクライアント間に接続が確立し,その後プロキシとサーバー間で接続を確立する. (必要作業として,クライアント要求をプロキシに向ける必要がある)
Simple Implementation
プロキシの作成はCanape CoreライブラリのTCPポートフォワーダーを用いる. 上図のC#スクリプトの2にプロキシが接続を待機するポートを設定し,3, 4に本来の宛先情報を設定する.
- 5: プロキシインスタンス生成, 開始
- 6: キャプチャ終了
- 7: 結果を出力
注意: プロトコルテストのためのプロキシは堅牢なセキュリティ機構を持たないことが多いため,プロキシをすべてのネットワークアドレスにバイドすることは危険になる可能性があるため,極力ローカルループバックインターフェイスにのみ用いた方が良い.上のデフォルトはLOCALHOSTである.全インターフェイスにバイドするにはAnyBindの値をtrueにする.
Ridirecting Traffic to Proxy
ウェブブラウザならURLにlocalhost:portを指定するのみ. 他のアプリケーションの場合,IPアドレスのみを変更できるなら宛先をlocalhostに変更し,ポート番号は,使用しているポート番号を調査した上でプロキシサーバーの待機ポートを調整する. アプリケーションが複数の接続を確立する場合,(例えば,Common Object Request Broker Architecture(CORBA),Remote Procedure Call(RPC)で発生する)パッシブキャプチャで通常用いる複数の接続ポートを調査し,プロキシインスタンスを複数用意する必要がある. アプリケーションが宛先変更を許可しない場合,ただしホスト名解決をする場合は自分のカスタムDNSを用意するか,ローカルのDNSキャッシュ,ローカルのホスト名解決テーブルを変更して対処する. ローカルのテーブルはUnix系なら/etc/hosts,WindowsならC:\Windows\System32\Drivers\etc\hosts. ただし,このようなホスト名テーブルの変更はマルウェアが行いがちな挙動であるため,ウィルス対策ソフトに検知される必要があるため,hostsファイルを変更したい場合はソフトウェアの保護を無効にする必要がある.
Advantages of a Port-Forwarding Proxy
単純さが利点である.アプリケーション側のサポートが不要である.
Disadvantages of a Port-Forwarding Proxy
単純さが欠点である.リッスン接続から単一の宛先にトラフィックを転送するのみのため,アプリケーションが複数のプロトコルを持つ場合プロキシが複数必要になる.
- 宛先に単一のホスト名かIPアドレスがあり,ホスト名偽装か,IPの設定の書き換えでアドレスのみ制御できる場合,アプリケーションはTCPポート443, 1234に接続要求.1234のみキャプチャしたい場合でも,443宛もlocalhostにやってくるため,両方に転送プロキシを設定する必要がある.
- プロキシが1234をリッスンし,www.domain.com:1234に接続している状況で,www.badgers.com:1234をリダイレクトしたい場合,困難となる.
アプリケーションがアドレスとポートの指定をサポートするならDNATなどでこれらを軽減可能である. HTTPのようにプロトコルによっては自身のヘッダ中に宛先アドレスを格納する場合がある.(これはリバースHTTPプロキシで回避)
- SOCKS Proxy
SOCKSプロキシは単純な転送だけでなく,複数の接続先の確立が可能である. そのため,アプリケーションサーバーがデータ送信のために新規ポートを開くようなFTPもサポート可能である. SOCKSにはver4, 4a, 5があり,ver4は最も一般的なものであり,メッセージフォーマットは下図のようになる. クライアントはリクエストに宛先ポート番号,宛先アドレスを指定し,ユーザ名で認証を行う(安全性はない). レスポンスのアドレス.ポートフィールドはバインディング要求にのみ利用.
ver 4はIPv4のみサポートで,ホスト名は用いることができない. ver 4aはホスト名による接続が許可(DNSがない場合に便利). ver 5はIPv6, UDP転送,認証メカニズムの改善が導入.
Simple Implementation
Canape CoreライブラリはSOCKS4, 4a, 5をサポートしており,プロキシサーバーはC#スクリプトで作成可能. 2のLOCALPORTをリッスンしたいポートに設定.
Redirecting Traffic to Proxy
トラフィックをプロキシに向けるには.ブラウザなら下図のようにプロキシ設定を行う.
Javaアプリケーションなどプロキシ設定が組み込まれていない場合,JavaランタイムはSOCKSサポートを有効にするコマンドラインパラメータが存在する.下のJavaコードはポート5555, IPアドレス192.168.10.1に接続するTCPクライアントである.
コンパイル済みプログラムにSOCKSプロキシを適用するには次のようにすれば良い.
$ java –DsocksProxyHost=localhost –DsocksProxyPort=1080 SocketClient
最終的にアプリケーションの設定が不可能な場合はOSのデフォルトプロキシの設定である. システム全体の通信をSOCKSプロキシに通すようにすれば良い. 他にはツールによってアプリケーションに機能を追加する方法がある.(Dante, Proxifier)
Advantages of SOCKS Proxy
アプリケーションのすべてのTCP接続をキャプチャ可能な点. FTPのようにサーバー側からコネクト要求があるようなプロトコルのためにプロキシサーバーがリッスンできる点.
Disadvantages of SOCKS Proxy
WindowsシステムプロキシはSOCK 4のみをサポートしIPv6をサポートせず,堅牢な認証メカニズムを持たない. SOCKSツールの導入により堅牢性を高ようとしてもOSとの問題でうまくいくとは限らない点.
- HTTP Proxy
HTTPプロキシはアウトバウンドトラフィックのHTTP通信を中継する. HTTPプロキシは制限の厳しいファイアウォールを通過するため,JavaのRMI(Remote Method Invocation)やRTMP(Real Time Messaging Protocol)などの非webの転送機能にも使われる.
Forwarding an HTTP Proxy
HTTP1.1のリクエストの最初は次の形式をとる.
GET /image.jpg HTTP/1.1
メソッドにGET/POST/HEADなどを指定し,リクエストの捜査内容を指定. プロキシへのリクエストも同様である. パスは要求リソースを指定するが,絶対URIを指定することもできる. 絶対URIを指定することで,プロキシサーバーは宛先への接続を確立しトラフィックを転送し,データをクライアントに返す. プロキシは認証機能を追加することもできる. プロキシへのHTTPリクエストは次の形式をとる.
GET http://www.domain.com/image.jpg HTTP/1.1
HTTPプロキシサーバーはHTTPリクエストを解釈できなければならない. また,HTTPSについて,クライアントはプロキシサーバーと接続するため,クライアントサーバーの証明書を受け取るが,この証明書が信頼されることはほとんどない. それゆえ,HTTP1.1以降導入されたCONNECTリクエストを用いて,HTTPSサーバーへのプロキシを介した接続は次の形式をとる.
CONNECT www.domain.com:443 HTTP/1.1
プロキシがこの要求を受信すると,サーバーへ新規TCP接続を確立する. 成功すると次のメッセージを受信する.
HTTP/1.1 200 Connection Established
これによりブラウザとサーバー間で接続が確立する. プロキシは暗号化されたHTTPリクエストを受信するとIP, ポートのみを変更しサーバーに転送する. プロキシはCONNECTリクエストがTLSをトンネリングしていることを検証しない. つまり,HTTPプロキシを用いて通っている通信は独自のプロトコルの可能性もあるため悪用することができる. そのため,一般的にはトンネリング可能なポートを制限する.
Simple Implementation
Canape CoreライブラリはCONNECTメソッドをサポートしていない. HTTPプロキシの作成では2にローカルポートを指定する.
Redirecting Traffic to Proxy
HTTPを用いるアプリケーションはプロキシ設定を持つ. ブラウザ,OSの他に,curl, wget, aptなどのコマンドラインツールも環境変数による設定が可能.
Advantages of a Forwarding HTTP Proxy
利用するために必要なことはHTTPリクエストのパスを絶対URIにし,リクエストをプロキシに送信するのみで可能な点.
Disadvantages of a Forwarding HTTP Proxy
完全なHTTPパーサーを実装する必要があるためプロキシの実装は複雑. HTTP1.1接続処理は複雑なため,通信をHTTP1.0にダウングレードするのが一般的. そのため,一部のアプリケーションに不具合を発生させうる.
- Reverse HTTP Proxy インバウンドHTTPトラフィックを中継する. ロードバランシングやセキュリティの理由(サーバーを直接公開しない)で用いる. 実現にはHTTP1.1でクライアントはHTTP ヘッダにホスト名を含めなければならない点を利用する. 次のリクエストはURL”http://www.domain.com/image.jpg” に対するものであると示す リバースプロキシはこの情報から本来のサーバーへのリクエストを構築する. TLSで暗号化されたHTTPSトラフィックに使用することは困難である.
Simple Implementation
Redirecting Traffic to Your Proxy
リクエストをプロキシに向けるにはhostsファイルを編集するかDNSサーバーを構築する. もしくは,DNSリクエストに対してプロキシのアドレスを返すツールを利用する. ここではCanapeのDNSサーバーを構築する. 1, 2にサーバーのアドレス,3を適当な文字列に設定. これはすべてのDNS要求に単一のIPドレスのみを偽装する.
Advantage of a Reverse HTTP Proxy
クライアントアプリケーション側で設定が必要ない点.
Disadvantages of a Reverse HTTP Proxy
HTTPリクエストを解析する必要がある点.
Final Words
本章では,受動的キャプチャ手法,能動的キャプチャ手法を説明した. ネットワークトラフィック監視以外の場合は能動的キャプチャ手法を勧める. 後々,アクティブなキャプチャはプロトコル分析と活用によって便利であるとわかるだろう. その中でも可能ならSOCKSを用いると良いだろう.