例としてMicrosoft Edgeを使用する任意のコードガード(ACG)メカニズム

免責事項
  • この出版物は、Ivan Fratric(Google Project Zero) によるドキュメント「Microsoft EdgeでJITサーバーを攻撃することによる緩和策の回避の一部の翻訳です。 ACGメカニズムとMicrosoft Edgeブラウザーでのそのアプリケーションを説明する部分は翻訳されています。 この翻訳以外では、Chakra(Microsoft Edge JavaScript Engine)のJITの内部の詳細な説明とその攻撃ベクトル(発見された脆弱性の説明、ドキュメントの公開時に修正)が残りました。
  • 私の職業活動の性質上、私はテクニカルライターでもありませんし、(さらに)翻訳者でもありません。 しかし、ドキュメントの内容は、Windowsの内部を研究するという点で非常に興味深いように思えました。 したがって、翻訳を改善するための建設的なコメントと提案を受け付けています。




Windows 10 Creators Updateのリリースにより、MicrosoftはMicrosoft Edgeの新しいセキュリティメカニズムであるArbitrary Code Guard(ACG)の使用を開始しました。 ACGをプロセス(特に、Microsoft Edgeプロセス)に適用すると、ターゲットプロセスで新しい実行可能メモリを割り当てたり、既存の実行可能メモリを変更したりすることができなくなります。 したがって、攻撃者にとっての任意のコードの実行はより困難になります。



パフォーマンスを向上させるために、最新のブラウザーはJavaScriptコードのJIT(Just-In-Time)コンパイルを使用しますが、このアプローチはACGと互換性がありません。 そのため、Microsoft Edgeには次のアプローチが実装されました。JITは、コンテンツプロセス(コンテンツプロセス)に関連する個別のプロセスに分離されました。 コンテンツプロセスはJavaScriptバイトコードをJITプロセスに送信し、JITプロセスはそれをマシンコードにコンパイルし、そのマシンコードをコンテンツプロセスに投影します。



Microsoft EdgeでのACGの機能



ACGは、動的プロセスコードポリシーの設定に依存します。 このポリシーは、ProcessDynamicCodePolicyパラメーターを指定してSetProcessMitigationPolicy関数を呼び出すことにより、任意のWindowsプロセスに設定できます。 Microsoft Edgeコンテンツプロセスでは、呼び出しは次のとおりです。



00 KERNELBASE!SetProcessMitigationPolicy 01 MicrosoftEdgeCP!SetProcessDynamicCodePolicy+0xc0 02 MicrosoftEdgeCP!StartContentProcess_Exe+0x164 03 MicrosoftEdgeCP!main+0xfe 04 MicrosoftEdgeCP!_main+0xa6 05 MicrosoftEdgeCP!WinMainCRTStartup+0x1b3 06 KERNEL32!BaseThreadInitThunk+0x14 07 ntdll!RtlUserThreadStart+0x21
      
      





各Microsoft Edgeコンテンツプロセスは、作成後すぐにこの関数を呼び出します。 残念ながら、1つのコンテンツプロセスが同じサンドボックス( App Container )で実行される他のコンテンツプロセスにアクセスできるため、コンテンツプロセスAはBがACGをアクティブにする前にコンテンツプロセスBにアクセスできます。 これにより、攻撃者はプロセスBでACGメカニズムがアクティブにならないことを確認できます(または、ACGメカニズムがアクティブになるまでプロセスBで任意のコードを実行するだけです)。 これ公開時点で修正されていない アーキテクチャの問題であり、Windowsの将来のバージョンで解決される予定です。



動的コードポリシーは、Microsoft Edgeコンテンツプロセスによって常に設定されるとは限りません。 このポリシーの適用を決定する前に、プロセスは次の図に示すように、いくつかのレジストリエントリにアクセスします。







幸い、Microsoft Edgeコンテンツプロセスにはこれらのレジストリキーへの書き込みアクセス権がないため、侵害されたコンテンツプロセスは、将来作成されるプロセスのACGを単純に無効にすることはできません。



さらに、後方互換性を確保するために、Edgeは動的コードポリシー値を設定する前に、ACGと互換性のないドライバー(グラフィックスなど)が存在するかどうかを判断しようとします。 ACGに関するMicrosoftブログ投稿

互換性の理由から、ACGは現在、メインGPUがWDDM 2.2ドライバー(Windows 10 Anniversary Updateでリリースされたドライバーモデル)を実行している64ビットマシン、またはソフトウェアレンダリングを使用する場合にのみ使用されます。 実験目的のために、[コントロールパネル]-> [インターネットオプション]-> [詳細]を使用して、ソフトウェアレンダリングを強制的に有効にすることができます。 現在、Microsoftデバイス(Surface Book、Surface Pro 4、Surface Studio)およびGPUドライバーがACGと完全に互換性のある他のいくつかのシステムはACGを使用しています。 テレメトリと顧客レビューを評価する際に、サポートされるGPUのリストの範囲と精度を改善する予定です。





つまり、古いGPUドライバーを搭載した多くのシステムでは、コンピューターがWindowsの更新バージョンを実行している場合でも、ACGメカニズムは有効になりません。



プロセスで動的コードポリシーが有効になっていることを確認するには、次の図に示すように、PowerShellスクリプトGet-ProcessMitigationを呼び出します。







特に注目すべきは、エントリ「AllowThreadOptOut:OFF」です。 Windowsの以前のバージョンでは、このオプションは「オン」であり、ACGの下から終了できました。 これは、予想どおり、メカニズムが非常に非効率的であるという事実につながりました。



Microsoft EdgeコンテンツプロセスはSetProcessMitigationPolicy()を呼び出すときに、AllowRemoteDowngradeフラグも設定します。これにより、非AppContainerプロセスはいつでもポリシーを無効にできます。 これは、ディスプレイドライバーが変更されたときに使用されます。 コンテンツプロセス自体から動的コードポリシーを無効にしようとすると、包含後にERROR_ACCESS_DENIEDエラーが発生します。



前述のように、動的コードポリシーが有効になっている場合、それは不可能になります。



  1. 新しい実行可能メモリを割り当てます
  2. 既存の実行可能メモリを変更する


つまり、引数flProtect / flNewProtectのフラグが実行可能メモリに関連している場合、 VirtualAllocおよびVirtualProtect関数の呼び出しは失敗します。 これは、MapViewOfFileなど、同様の効果を引き起こす可能性のあるすべての関数に適用されます。 ACGが原因で関数が失敗すると、新しいエラーコード0xc0000604、STATUS_DYNAMIC_CODE_BLOCKEDが返されます。



プロセスAがプロセスBで実行可能メモリを割り当てようとすると、プロセスAのポリシーのみが重要になります。つまり、プロセスBで動的コードポリシーが設定されている場合(ACGメカニズムが有効)、プロセスAではそうではない場合、プロセスAからの呼び出しは成功しますプロセスAが適切な権限を持つプロセスBへのハンドルを持っている場合。



したがって、ACGメカニズムを有効にしたプロセスで実行可能メモリを割り当てる唯一の方法は次のとおりです。



  1. ACGメカニズムが無効になっている別のプロセスによる実行可能メモリの割り当て
  2. プロセスへのdllのロード


2番目の状況を処理するために、Microsoftは別のメカニズム-CIG( Code Integrity Guard )を提供しています。 CIGメカニズムを有効にすると、プロセスはMicrosoft署名付きDLLファイルのみをロードできます。



ACGはどれくらい効果的ですか?



実行可能メモリを割り当てることができない状況で、サイバー犯罪者が使用するいくつかのアプローチがあります。



  1. 攻撃者が現在のプロセスを終了する必要がない場合、データのみの攻撃を実行できます(実行不可能なメモリのみを使用します)。 ブラウザーの場合、これは対応するフィールドを上書きしてポリシーチェックを無効またはトリックすることを意味します。これはユニバーサルXSS攻撃に相当します(注:サイト分離を有効にしたGoogle Chromeでは、このような攻撃の実装は非常に複雑です)。
  2. そうでない場合、攻撃者がスクリプトを利用できない場合、唯一の方法はROPなどの既存のコードを再利用することです。 攻撃者がROPを使用してペイロードメモリ領域を実行可能にし、そこに制御を移すことだけができないことは注目に値します(今日のエクスプロイトでよく行われます)。 代わりに、すべてのペイロードをROPに書き込む必要があります。 これは現在、時間のかかるタスクですが、ACGの大規模な使用は、このタスクを容易にする自動化ツールの開発に対するインセンティブを提供する可能性があります。
  3. スクリプト実行環境が存在する場合、攻撃者は3番目の(より単純な)アプローチを使用します。 ROPにペイロードを書き込む代わりに、読み取りおよび書き込みプリミティブを持つ攻撃者は、このプロセスに既に存在するスクリプトランタイム(たとえば、EdgeのJavaScript)を使用できます。 これにより、以下を許可するインターフェースが作成されます。



    • スクリプトランタイムから任意の引数を使用して任意のネイティブ関数を呼び出す
    • 戻り値をスクリプトランタイムに戻す


    このような機能を備えたエクスプロイトライブラリを使用すると、攻撃者はネイティブコードでペイロードを記述する代わりに、必要に応じてネイティブコール用のライブラリを使用して、スクリプト言語でコードを記述します。 メンテナンスライブラリがmalloc()、memcpy()などの補助メソッドを提供する場合、タスクは大幅に簡素化されます。 実際、そのようなライブラリーpwn.jsは既に存在します



    攻撃者は、任意のネイティブ関数を呼び出すことができる代わりに、任意のシステムコール(syscalls)を実行できる可能性があります。



上記から、特にWebブラウザではACGはあまり役に立たないように思えるかもしれませんが、シナリオ2および3は、制御フローをキャプチャできる攻撃者を想定していることを考慮する必要があります。 つまり、攻撃者はCFG(Control Flow Guard)をバイパスする必要があります。



現在、 多数のよく知られたアプローチにより、WindowsのCFGバイパスは難しくありません。 ただし、Microsoftがすべての既知のCFGの欠陥を修正できる場合(およびMicrosoftが既にこれを行う意向を示している場合)、今後数年で状況が変わる可能性があります。



したがって、ACGの使用の成功は、CFGおよびCIG( コード整合性ガード )の使用の成功に直接依存します。 これらのメカニズムはすべて、悪意のあるコードの実行を防ぐために連携する必要があります。





チャクラ(JITサーバー)



ACGメカニズムを有効にしてChakra(Microsoft EdgeのJavaScriptエンジン)にJITを実装するために、Microsoftは、JITサーバーという別のプロセスでコードをコンパイルする責任があるChakraの部分を実行します。 コンテンツプロセスとJITサーバー間の主な相互作用を次の図に示します。







このアーキテクチャでは、コンテンツプロセスは、JavaScriptのコンパイル(JIT)を除く、JavaScriptの実行に関連するすべてのタスクを処理します。 JavaScript関数(またはループ)をネイティブコードにコンパイルする必要があるとChakraが判断すると(通常、これはスクリプトの同じ部分を数回解釈した後に発生します)、現在のプロセスでこれを行う代わりに、JITサーバーが呼び出され、これが渡されますターゲット関数のバイトコード。 次に、JITサーバーはバイトコードをコンパイルし、結果の実行可能ネイティブコードを共有メモリ(セクションオブジェクト)を使用して呼び出しプロセスに書き戻します。 その後、コンテンツプロセスは、動的コードポリシーに違反することなく、結果の実行可能コードを実行できます。



実行中のプロセスの観点から見ると、JITサーバーは他のコンテンツプロセスと同じように見え、同じexeファイルであるMicrosoftEdgeCP.exeを使用します。 大きな違いは、ACGメカニズムがJITプロセスに対して有効になっていないことです。これにより、実行可能コードをコンテンツプロセスに投影し直すことができます。 この場合、1つのJITサーバープロセスのみが起動され、既存のすべてのコンテンツプロセスを処理します。



おわりに



ACGは、実行可能なメモリの割り当てと変更を防ぐという当面の目標を達成することに成功しています。 ただし、一方ではCFG、ACG、CIGの相互依存性、および他方ではMicrosoft Windowsでの現在のCFG実装の欠点のため、ACGは高度な攻撃がブラウザのサンドボックスから出るのを防ぐための十分な手段ではありません。 したがって、ACGが悪用の重大な障害になる前に、Microsoftは既知のCFGのすべての欠陥を修正する必要があります。



All Articles