
このブログは、2つの連鎖したバグについてのものです。ステージ1はROOTドライブの再マッピングによって引き起こされるDLLハイジャックバグであり、ステージ2はCSRSSサーバーによって管理されるアクティベーションキャッシュポイズニングバグです。
最初のステージは、Ekoparty 2023において、BlueFrost SecurityのNicolás Economou氏による「I'm High」というプレゼンテーションで詳細に発表されました。彼は、当時まだMicrosoftによってパッチが適用されていなかった脆弱性をどのように悪用するかを説明しました。これにより、MEDIUM INTEGRITYのユーザーが昇格して限定的なHIGH PRIVILEGESを取得できるようになりましたが、完全なAdministratorになるための完全なアクセス権はありませんでした。
2番目のステージはそのカンファレンスでは発表されませんでしたが、研究を始めるためのいくつかの手順が示唆されました。
まず、導入の文脈として最初のステージを復習します。そこから、2番目のステージに関する私の研究に進み、限定的なHIGH INTEGRITYから完全なAdministratorへの完全な昇格を達成する詳細を掘り下げます。これには、すべてのWindowsバージョン向けの両ステージの完全な動作PoCが含まれており、Windows 10、Windows 11、Windows Server 2022、Windows Server 2019で、すべての更新プログラムが適用された状態で正常にテストされています。

このステージの唯一の要件は、初期プロセスがMEDIUM INTEGRITY LEVELで開始され、ユーザーがAdministratorグループに属していることです。
最初のステージの悪用は、以下の手順に要約できます。
例: ディスクを
"C:\" から "C:\users\public" に再マッピング
これにより、"system32"フォルダも
"C:\windows\system32" から "C:\users\public\windows\system32" に再マッピングされます
影響を受けるプログラムの1つはCTFMONで、これはHIGH INTEGRITY LEVELで実行されますが、Administrator権限はありません。
通常、実際のsystem32フォルダからMsCtfMonitor.dllというモジュールをロードしようとしますが、ROOTドライブが再マッピングされたため、私たちの制御する偽のsystem32内で同じ名前のDLLを作成して配置できる場所でMsCtfMonitor.dllを探します。
この時点で、偽のsystem32フォルダに私たちのバージョンのMsCtfMonitor.dllを配置することで、そのDoMsCtfMonitor関数が呼び出され、HIGH INTEGRITY LEVELで私たちのコードが実行されます。




同時に、プロセスがHIGH INTEGRITY LEVELであるにもかかわらず、Administrator権限を持っていないことを確認できます。


NicolasはEkopartyのプレゼンテーションで、悪用を完了するための以下の手順を提案しました。


これは単純に見えますが、リバーシングとデバッグに多くの時間を要します。
この攻撃ベクトルの歴史を少し掘り下げると、アクティベーションコンテキストキャッシュの汚染がいくつかのエクスプロイトで使用されてきたことが明らかになりました。したがって、以前にどのように悪用が行われてきたかを学ぶことは、追加の文脈と洞察を提供するために価値があります。この悪用の詳細は、Zero Day Initiativeの記事『Activation Context Cache Poisoning: Exploiting CSRSS for Privilege Escalation』で入手できます。
アクティベーションキャッシュの使用は、プログラムが特定のバージョンを必要とするライブラリをロードするときに発生します。
例えば、アプリケーションがC:\Windows\System32\comctl32.dllをロードしようとする場合、その場所にあるcomctl32.dllがアプリケーションが必要とするバージョンである保証はありません。これがアクティベーションコンテキストキャッシュの基本的な使用例です。プログラムはCSRSSサーバーにリクエストを送信して、新しいアクティベーションコンテキストエントリをキャッシュに追加し、そのプログラムが必要とする特定のライブラリバージョンをロードできるようにします。
この目的のために、いわゆるマニフェストが使用され、XML形式で記述されます。通常はEXEまたはDLLファイルにリソースとして埋め込まれます。あるいは、Windowsはプログラムの実行可能ファイルと同じフォルダ内のマニフェストファイルを検索します。
上記のURLには、古いエクスプロイトで使用されたマニフェストファイルの例がいくつかあります。例えば、PATH TRAVERSAL手法によって攻撃者が制御するディレクトリからライブラリadvapi32.dllをロードするようにシステムを騙すものなどです。

もちろん、一部の使用された攻撃ベクトルはパッチが適用され、新しい手法が発見されました。さらに、Windows 11 22H2向けの2022年10月のパッチで、新しいチェックが追加されました。
このパッチが実装された後、Activation Context (ACTX) が登録される際のチェックは、キャッシュに新しいエントリを追加するプロセスが、それを使用するプロセスと同じかそれ以上のRIDを持つ場合にのみバイパスできます。
winnt.hでRID値を確認できます。

このチェックをバイパスする提案は、細工されたDLLが実行されるCTFMONプロセスからActivation Contextを含むリクエストを作成することです。この細工されたDLLはRID=0x3000を持ち、エントリがキャッシュに追加された後、RID=0x3000のTCMSETUPがtapi32.dllをロードします。
手順に従おうとした際、CreateActCtx を使用してACTXを登録するすべての可能な組み合わせを試しました。これを避けるチェックが常に存在するため、不可能であることが判明しました。
この関数はユーザーランドにあり、kernel32.dllによってエクスポートされていることに注意することが重要です。チェックはメモリ内のDLLにパッチを適用することで回避できます。これは非常にエレガントではありませんが、可能であり、機能するはずです。

NicolasのプレゼンテーションスライドはLOW LEVELを使用することを示唆しています。しかし、ウインクの顔に注目すると、パッチなしでこのバグを悪用する場合、CreateActCtxを使用することは最善の選択肢ではないことが明らかです。

Advanced Local Procedure Call (ALPC) は、Windowsオペレーティングシステム内で高速にメッセージを送信するために使用されるプロセス間通信メカニズムです。標準のWindows APIとは異なり、ALPCはアプリケーションから直接利用することはできません。代わりに、Windowsオペレーティングシステムのコンポーネントのみがアクセスできる内部メカニズムです(そして私たちも)。
さらに調査を進めると、いくつかの古いキャッシュポイズニングエクスプロイトがALPCを使用してサーバーと直接通信していたことに気付きました。例として、Philip Tsukermanの記事『Activation Contexts—A Love Story』を参照できます。
CsrClientCallServer関数は、Win32プロセスとCSRSSプロセス間のALPCインターフェースを実装しています。
したがって、サーバーとして機能するCSRSSプロセスに対してCsrClientCallServerを使用して呼び出しを試みる必要があります。
古いエクスプロイトの例を探していると、Packet Stormで関連するヒープバッファオーバーフローの問題に関するページを見つけました。
CSRSSサーバーが正しいパッケージで呼び出されると、モジュールsxssrv.dllに属するBaseSrvSxsCreateActivationContextFromMessage関数で受信されます。
この関数は引数が1つだけあります。受信したパケットへのポインタです。これをリバースするために、カスタムのTotalMessage構造体を作成しました。
TotalMessage構造体パケットは、最初の0x40バイトがHEADERで、その後ろに埋め込まれたActivation Context Messageが続き、その構造体は**_BASE_SXS_CREATE_ACTIVATION_CONTEXT_MSG**です。
TotalMessage構造体は以下のとおりです。

そして、_BASE_SXS_CREATE_ACTIVATION_CONTEXT_MSG構造体は次のとおりです。

この構造体の中には、言語またはCultureFallbacks、AssemblyDirectory、TextualAssemblyIdentity、AssemblyNameに対応する6つのUNICODE_STRINGSと、それぞれ内部に1つのUNICODE_STRINGを含む2つの**_BASE_MSG_SXS_STREAM**構造体があります。
以下は**_BASE_MSG_SXS_STREAM**構造体です。
