
ChakraCore のエクスプロイト技術
CVE-2016-7190 [0] は、ChakraCore の Array.map() 関数におけるヒープオーバーフローであり、隣接するメモリを上書きすることができます。任意読み取り/書き込みアクセスを得るための主なアイデアは、まず連続する複数の JavaScript 整数配列を割り当て、オーバーフローを利用して1つの配列のサイズを操作することです。次に、この配列を利用して Uint8Array のベースアドレスを読み書きしたい任意のアドレスに変更します。この追加のステップが必要な理由は、オーバーフローがオーバーフローした整数配列のサイズの最大2倍に制限されているためです。
この脆弱性は、異なる搾取戦略をテストするのに非常に適しています。なぜなら、現在のバージョンの ChakraCore に容易に再導入できるからです(undo-cve-2016-7190.patch を参照)。
この例では、Uint8Array C++ オブジェクトの vtable ポインタを制御されたメモリアドレスに上書きし、Uint8Array オブジェクトの関数を呼び出すことで仮想関数の呼び出しを引き起こし、制御フローをハイジャックします。
制御フロー完全性(CFI)は、制御フローハイジャック攻撃を緩和する防御技術です。CFI の一般的な考え方は、コンパイル時にアプリケーションの制御フローグラフ(CFG)を計算し、実行時に制御フローが静的に計算された CFG から逸脱しないようにランタイムチェックをアプリケーションに組み込むことです。しかし、Webブラウザのようなアプリケーションが動的コード生成をサポートする場合、CFG は実行時に拡張可能でなければなりません。これにより、いくつかの課題が生じます:
私たちが研究を行った当時、私たちは最後の課題に焦点を当てました。主なアイデアは、ジャストインタイム(JIT)コンパイラの入力(データ)を操作することです。その結果、JIT コンパイラは悪意のあるコードを生成し、それが現在のコンテキストに統合され、CFI で強化されることさえあります。私たちの研究と同時期に、theori [4] は JIT コンパイラの出力を操作することで CFI をバイパスする方法を示しました。この攻撃はチェックサムによる出力の整合性検証によって緩和されます。これは私たちの攻撃を止めることはできません。なぜなら、私たちは JIT コンパイラの入力を操作するからです。しかしながら、JIT コンパイルを別のプロセスに外部委託することにより(別名 Arbitrary Code Guard [3])、両方の攻撃が緩和されます。
私たちは 攻撃者が JIT コンパイラに対するデータオンリー攻撃を悪用して任意のネイティブコードを生成できることを示します。具体的には、JIT コンパイラの中間表現(IR)を変更して、攻撃者が制御する命令を注入します。JIT コンパイラが変更された IR に基づいてネイティブコードを生成すると、攻撃者が制御するネイティブコードが生成されます。
研究が最初に行われた時点から現在までに、ChakraCore の IR が変更されました。私たちは攻撃の移植に尽力しなかったため、この攻撃を試すには以下のバイナリを使用してください。
ACG [3] の分析中に、私たちは他の [1,2] とともに、.mrdata セクションに保存されているグローバル読み取り専用データが、動的に生成されたコードを統合するために調整されなければならないことに気付きました。これは LdrProtectMrdata() 関数によって行われ、ロックを使用してスレッドセーフにします。しかし、.mrdata セクションはロックが取得される前に最初に書き込み可能として再マッピングされます。興味深いことに、.mrdata セクションには .mrdata セクションのベースアドレスとサイズが含まれており、後でこのセクションを再度読み取り専用に再マッピングするために使用されます。
攻撃者はこれを悪用して、読み取り専用メモリを書き込み可能に再マッピングできる攻撃プリミティブを作成できます。そのため、攻撃者は以下の手順を実行します:
この攻撃の結果、以前は信頼されていたデータ、すなわち読み取り専用としてマッピングされていたデータが信頼できなくなります。私たちの概念実証では、このプリミティブを悪用して Control-flow Guard (CFGuard) をバイパスします。_guard_dispatch_icall_fptr に保存されている CFGuard の検証関数へのポインタを変更することにより行います。その効果は、デバッガをアタッチして bypass_cfguard 変数を変更することで観察できます。
[0] https://bugs.chromium.org/p/project-zero/issues/detail?id=923
[1] http://alex-ionescu.com/publications/euskalhack/euskalhack2017-cfg.pdf
[2] https://sites.google.com/site/bingsunsec/dataonlyattack
[3] https://blogs.windows.com/msedgedev/2017/02/23/mitigating-arbitrary-native-code-execution/
[4] http://theori.io/research/chakra-jit-cfg-bypass