2018年2月、GoogleのProject ZeroはMicrosoft Edgeのバグを公開しましたが、レドモンドは次回のパッチリリースまでにこのバグを修正できませんでした。現在、Googleの研究員であるIvan Fratric氏がこの問題の詳細な技術的説明を提供し、Microsoftの修正は不十分である可能性があると述べています。
Fratric は、ジャストインタイム JavaScript コンパイル、Edge の Chakra JavaScript エンジン、および Arbitrary Code Guard 間の相互作用により、攻撃者に任意のコード実行ベクトルが提供されることを発見しました。
任意コードガード (ACG) は、コードが動的に変更されるのを防ぐように設計されており、2017 年 3 月に最新の機能強化が行われました。
Google、Microsoftが修正に苦労していたEdgeのバグを明らかに
続きを読む
Fratric氏は先週木曜日の投稿でこの問題について次のように説明しました。「Microsoft EdgeのコンテンツプロセスにACGを適用すると、プロセス内で新しい実行可能メモリを割り当てたり、既存の実行可能メモリを変更したりできなくなります。これは、ブラウザのコンテンツプロセスで既に何らかの権限を取得している攻撃者が任意のコードを実行することをより困難にすることを目的としています。」
このホワイト ペーパー (PDF) では、Fratric の攻撃についてさらに詳しく説明しています。攻撃ベクトルは、ACG が存在する場合に JavaScript のジャストインタイム (JIT) コンパイルがどのように機能するかに関連しています。
JIT は ACG と互換性がないため、Microsoft は、JIT を Edge コンテンツ プロセスの一部として実行するのではなく、JIT エンジンを独自のプロセスに組み込みました。
Chakra JavaScript エンジンは、JIT コンパイルが必要な関数に遭遇すると、バイトコードを JIT サーバーに渡します。JIT サーバーはバイトコードをコンパイルし、結果の実行可能コードを共有メモリを使用して呼び出しプロセスに書き戻します。
ホワイト ペーパーでは、これにより、コンテンツ プロセスは「動的コード ポリシーに違反することなく」JIT コードを実行できると説明されています。
攻撃対象領域へのもう一つの鍵は、メモリ破損の脆弱性から保護するために設計された制御フローガード(CFG)です。Fratricの論文では、ここでの攻撃ベクトルの一つとして、「戻り値は保護されていないため、戻りアドレスを上書きするだけでバイパスを成功させることができる」ことが指摘されています。通常、スタック上の戻りアドレスを上書きするには、攻撃者はまずスタックの位置を知る必要があります。Chakraバイトコードは、スタックの読み書きに使用できるオペコードを組み込むことで、この要件を排除しています。
ホワイト ペーパーに記載されている攻撃シナリオに進む前に、さまざまなメモリ マッピングとプロセスの相互作用について徹底的に説明します。
- 攻撃者は JIT 割り当てのアドレスを観察し、次のアドレスを予測します。
- 攻撃者は対応する JIT セクションをアンマップします
UnmapViewOfFile()
。 - 攻撃者は
VirtualAlloc()
メモリの回収を要求しますが、今回はPAGE_READWRITE
権限が必要です。 - 攻撃者は新しく割り当てられた場所にペイロードを書き込みます。
- 攻撃者は、JITサーバーがメモリ領域を実行可能にするまで待機します。その後、攻撃者はステップ4で記述されたコードに制御フローを転送するだけで済みます。
よくあることだが、修正はマイクロソフトが懸念していたほど難しくなかった。レドモンドはVirtualAllocEx()
呼び出しを削除するだけで済んだのだ。
ここには概念実証があり、その唯一の仮定は「攻撃者が、無関係の脆弱性を通じて、コンテンツ プロセスのメモリ読み取り/書き込みプリミティブをすでに取得することに成功している」というものでした。®