VxWorksの脆弱性「URGENT/11」が浮き彫りにしたTCP/IPスタックの“残念な実装”IoTセキュリティ(3/4 ページ)

» 2019年09月26日 10時00分 公開
[谷崎朋子MONOist]

TCPの緊急ポインタの定義が迷走、IPnetは“残念な実装”に

 一方の2.〜5.の脆弱性は、インターネットからNATもファイアウォールも乗り越えてリモートコード実行を可能にしてしまう、深刻な脆弱性だ。

 これらの脆弱性に共通するのは、TCPの緊急(URG)ポインタフィールドだ。TCPは、データを順番に転送するためのプロトコルだ。受け取ったデータは処理されるまで、TCPウィンドウと呼ばれるバッファーにためられる。だが、送信元がデータの処理を中止したい場合、またはデータをアプリケーション側にすぐに渡す必要が出た場合、TCPヘッダの緊急ポインタフィールドを有効(URGフラグが1)にしたパケットが送信される。このパケットは通常のデータストリームをスキップする形でアプリケーション側に渡されることから、アウトオブバンド(OOB)データと呼ばれる。OOBデータを受け取ると、ユーザーが受け取るデータ部分とURGデータ部分とを切り離して処理するのだが、このとき重要となるのが切り離す場所を指し示す緊急ポインタだ。

 この緊急ポインタの開始地点の定義で、技術仕様の保存と公開を行うRFC(Request for Comments)は揺れた。

 定義が最初に登場したRFC 793(1981年、17ページ)では、「緊急ポインタは、緊急データに続くオクテットのシーケンス番号を指す」と記載された。しかし、RFC 1011(1987年、8ページ)では「17ページの説明は間違い。緊急ポインタは、(緊急データ以外の最初のオクテットではなく)緊急データの最後のオクテットを指す」と再定義。その後、RFC 1122(1989年、84ページ)で「…‥緊急ポインタは、緊急データのシーケンス内の最後のオクテット(最後+1ではない)のシーケンス番号を指す」と追記され、ようやくRFC 6093(2011年、6〜7ページ)で決着。だが、今度は終了地点が示されていないから緊急データの長さが分からない問題が発生し、最終的に、緊急データは常に1オクテット(バイト)であるということで落ち着いたものの、迷走期間中に開発されたTCP/IPスタックの多くは“残念な実装”になってしまった。IPnetも、例に漏れない。

RFCでの定義の迷走ぶりを表す演出RFCでの定義の迷走ぶりを表す演出 講演では、RFCで緊急ポインタの開始地点の定義が迷走した様子をグループチャット風に演出。会場の笑いを誘った(クリックで拡大)

 IPnetは、他のOSのTCP/IPスタックと同様に、RFC 1122互換モードと非互換モード(緊急ポインタの±1のいずれかを緊急データとする)の両方をサポートする実装だ。しかし、なぜかデフォルトでは互換モードしかサポートされていなかった。つまり、デフォルトだと緊急ポインタから-1で緊急データの開始地点を決定することになる。

 この処理が原因で、ユーザーが受け取るデータと緊急データを切り離す際の計算が狂い、以下に挙げる4つの脆弱性が生み出された。

  • URGフラグが0設定のデータを受信したとき、アウトオブバンドデータと通常のデータの切り離し時に、IPnetは−1で緊急データの開始地点を計算。緊急データ以降のサイズ(len関数)は符号なし関数で扱うため、サイズは必然的に最大値(0xffffffff)をとってしまう。結果、TCPウィンドウにたまったデータを全部コピーすることになり、オーバーフローを引き起こす(CVE-2019-12255)
  • TCP-AO(TCP認証オプション)では、クライアントOSから最初のSYNを受け取ると新規にソケットを作成し、同じTCPパケットは同ソケットで受け取る処理をする。このとき、同ソケットと既存ソケットにSYNパケットが送られてきたとき、通常であればTCP接続を中断・拒否するのだが、IPnetは両方とも受け入れてしまい、競合状態が発生。すかさず3つ目のSYNパケットを送信してハンドシェイクを開始、その際に大きめのデータをTCPウィンドウに追加していき、あとは緊急ポインタの脆弱性を使ってオーバーフローを引き起こす(CVE-2019-12260)
  • ユーザーアプリがconnect()システムコールを実行してSYNパケットを送信したのに対して、攻撃者がFINフラグ(通信終了)とURGフラグを含めたSYN/ACKパケットを返した場合、パケットは破棄されるがソケットの待ち受け状態は継続。すかさずメモリコラプションを起こすようなデータを入れ込んだ別のSYN/ACKパケットを投げると、緊急ポインタの誤処理と似た状態に陥る(CVE-2019-12261)
  • 緊急ポインタの状態を示す関数は複数あるが、ユーザータスクで使用中でもカーネルタスクで個別に設定変更が可能であり、競合状態が発生。その状態で緊急ポインタの脆弱性を利用し、メモリコラプションを発生させる(CVE-2019-12263)

 緊急ポインタフィールドは通常、ルーターやNAT、ファイアウォールなどで有効だ。例えば、VxWorksがOSとして稼働しているファイアウォールに対して、細工されたTCPパケットをリモートから送信し、脆弱性を突いて乗っ取ることができれば、他の攻撃手法で内部のデバイスを全てbot化して、botネットを構築することも可能だ。

 また、プリンタがNAT越しにクラウドサービスと接続しているケースでも、例えばDNSをハイジャックするマルウェア「DNSpionage」を使ってTCP接続の間に割り込み、脆弱性を突いてプリンタを乗っ取ることができる。「これが成功すれば、IPのオプションフィールドの脆弱性で紹介したLAN内の攻撃シナリオの通り、横展開で他のVxWorksデバイスを乗っ取るのも簡単だ」(ズスマン氏)。

Copyright © ITmedia, Inc. All Rights Reserved.