Symantec Security Response Weblog
DirectShow Exploit In the Wild, Part II」より
June 19,2009 Posted by Liam O Murchu

 前回の記事(パート1)では,Windows用マルチメディア処理アプリケーション・インタフェース「DirectShow」に関して最近その存在が明らかになったセキュリティ・ホールについて,全体的な流れを紹介した。このセキュリティ・ホールをふさぐ修正パッチはまだ提供されていないため(6月19日時点),悪用が広まるのではないかと心配している。そこで今回は,このエクスプロイトを詳しく示し,仕組みを説明し,防衛につながる回避策を示す。

 手っ取り早く回避策を知りたければ,当記事の最後の部分を読んでほしい。このセキュリティ・ホールは,「Windows Vista」と「Windows Server 2008」には存在しない。

ぜい弱性

 このぜい弱性を悪用する攻撃者は,ユーザーを攻撃用のWebページに誘い込む。攻撃者は様々な手口のなかでも,無害なWebページにiframeタグを挿入するという手口に特に精通している。これは現在,最もよくあるパターンである。フィッシング・ページには既に,今回のエクスプロイトを指すiframeタグの存在が確認されており,こうしたWebページは増えていくと予想される。

 このぜい弱性は米マイクロソフトのマルチメディア機能「DirectX」用コードに関連したもので,特殊な細工を施したQuickTimeファイルによって問題が引き起こされる。攻撃者はWebページでユーザーに細工済みQuickTimeファイルを再生させようとするのだが,その際に米アップルの「QuickTime Player」でなく「Windows Media Player」を使うよう仕向ける。こうしてぜい弱性を突き,ユーザーのパソコンで攻撃用コードを実行させる(関連記事:「DirectX」にぜい弱性,QuickTime再生で遠隔コード実行の恐れ)。

 DirectXのぜい弱なコードは「quartz.dll」内にあり,1バイト長のNULLバイトを上書きする。つまり,攻撃者はこれを悪用しても,メモリーにNULLバイト・データを1バイトしか書き込めない。さらに,上書き可能なメモリーの範囲はぜい弱なコードから255バイト以内だけ,という別の制約も存在する。

エクスプロイト

 ぜい弱性悪用時のこうした制約は,エクスプロイトを作る上で無視できない条件だ。我々の調査した最近のエクスプロイトは,大多数がヒープ・スプレイという手口を使っている。これは,あらかじめメモリーの極めて広い領域に攻撃用コードを書き込んでおき,エクスプロイトを使ってその部分へ処理をジャンプさせる方法である。ところが今回の場合,攻撃者が悪用できるのは1バイトだけで,しかもその値はNULL(データ上はゼロ)になってしまうため,ヒープ・スプレイが使えるとは限らない。さらに,ヒープを書き込むメモリー領域は1バイトのアドレスで指せるような位置にないだろう(この領域のアドレスは,メモリーにロードされたquartz.dllの位置によって変わる。下図参照)。

 実際に出回っているエクスプロイトを調べたところ,攻撃者はぜい弱性を持つ関数のリターン・アドレス(処理の戻り先アドレス)内の1バイト(厳密には2バイト目)にデータを上書きする方法をとっていた。例えばこの関数のリターン・アドレスが本来0x74817677であるとすると,攻撃者はこれを0x74007677に書き換える。その結果プログラム処理は,この関数の最後に達すると書き換えられたアドレスへジャンプする。

 次に攻撃者は,0x74007677で待ち受けるコードを用意しなければならない。そのために自分のDLLをメモリーにロードする。このDLLをロードするアドレスは,quartz.dllに近いところ(今回の例では0x74000000)がよい。DLL内には大量のNOP命令(意味のないダミー命令)があり,実行させたいシェルコードまで導く。リターン・アドレスが0x74007677に書き換えられているため,プログラム処理は(0x74000000にロードされた)DLL範囲内のメモリーにジャンプし,攻撃者が制御権を獲得する。

 上の図だと,quartz.dllは0x74810000にロードされていて,攻撃者のDLL「12.dll」は0x74000000にロードされ,0x74014000(サイズはここから0x1000バイトある)まで続いている。このスクリーンショットを見ると,攻撃者がエクスプロイト実行に必要な条件をすべて満たしたことが分かる。

 ただし,まだ一つ問題がある。quartz.dllが必ず0x74810000にロードされるとは限らないことだ。ロード先のアドレスは,ロード時のメモリー使用状況によって全く異なる。0x74810000に何かがロード済みだと,quartz.dllは別の場所にロードされる。ロード先はロード処理時のメモリーの空き状況によって変わる。攻撃者には,quartz.dllがロードされる正確なアドレスをあらかじめ知る術はない。そこで今回の攻撃者は,いくつかの適切なアドレスにそれぞれDLLをロードするという対策を講じた。こうしてメモリー内にDLLを書き散らし(ヒープ・スプレイならぬDLLスプレイ),どれか一つの近くにquartz.dllがロードされるのを待つ。

 攻撃者は上図のように大量のDLL(7.dll,8.dll,9.dll,1.dll,2.dll,3.dll,4.dll,5.dll)をメモリーにロードし,quartz.dllが期待していた場所にロードされなくても,これらDLLのどれか一つが近くにあるようにしている。実際に試したところ,quartz.dllが0x0c000000の近くにロードされ,攻撃者の思惑通りになったことがある。