トラップされたCOMオブジェクトによるファイルレスの横移動

暗い青色に照らされたオフィスで、ノートPCでタイピングをしたり、タブレットを持ったりする男性の手のクローズアップ

コンポーネント・オブジェクト・モデル(COM)は、1990年代初頭以来、Microsoft Windows開発の基礎となっており、最新のWindowsオペレーティング・システムおよびアプリケーションでも引き続き広く普及しています。COMコンポーネントへの依存と長年にわたる機能開発により、広大な攻撃対象領域が生まれてきました。2025年2月、Google Project ZeroのJames Forshaw氏(@tiraniddo)は、分散型COM(DCOM)リモート・テクノロジーを悪用する新たな手法を詳述したブログ記事を公開しました。この手法では、トラップされたCOMオブジェクトを利用して、サーバーサイドのDCOMプロセスのコンテキスト内で.NETマネージド・コードを実行できます。Forshaw氏は、権限昇格とProtected Process Light(PPL)バイパスの複数のユースケースを取り上げています。

2025年3月初旬、Forshaw氏の研究を基にMohamed Fakroud氏(@T3nb3w)は、PPL保護を回避する手法の実装を公開しました。Jimmy Bayne氏(@bohops )と私は2025年2月に同様の研究を行い、トラップされたCOMオブジェクトを悪用した概念実証のファイルレス横移動手法を開発しました。

背景

COMはバイナリー・インターフェース標準であり、基盤となるプログラミング言語に関係なく、個別のモジュール式コンポーネントを公開して相互に対話させ、アプリケーションとやり取りできるようにするミドルウェア・サービス層です。たとえば、C++で開発されたCOMオブジェクトは.NETアプリケーションと簡単にインターフェースをとれるため、開発者はさまざまなソフトウェア・モジュールを効果的に統合できます。DCOMは、COMクライアントがプロセス間通信(IPC)または遠隔手続き呼び出し(RPC)を介してCOMサーバーと通信することを可能にするテクノロジーです。多くのWindowsサービスは、ローカルまたはリモートでアクセスできるDCOMコンポーネントを実装しています。

COMクラスは通常、Windowsレジストリー内に登録され、格納されます。クライアント・プログラムは、COMオブジェクトと呼ばれるCOMクラスのインスタンスを作成することによって、COMサーバーと対話します。このオブジェクトは、標準化されたインターフェースへのポインターを提供します。クライアントはこのポインターを使用してオブジェクトのメソッドとプロパティにアクセスし、クライアントとサーバー間の通信と機能を促進します。

COMオブジェクトは、脆弱性の露出状況を評価し、悪用可能な機能を発見するための研究対象となっていることがよくあります。トラップされたCOMオブジェクトは、COMクライアントがプロセス外のDCOMサーバーでCOMクラスをインスタンス化するバグ・クラスであり、クライアントは、参照によってマーシャリングされるオブジェクト・ポインターを介してCOMオブジェクトを制御します。状況によっては、この制御ベクトルはセキュリティー関連のロジック上の欠陥を引き起こす可能性があります。

Forshaw氏のブログでは、WaaSRemediation COMクラスで公開されているIDispatchインターフェースを操作して、トラップされたCOMオブジェクトの悪用と.NETコードの実行を行うPPLバイパスのユースケースが説明されています。WaaSRemediationは、NT AUTHORITY\SYSTEMのコンテキストで保護されたsvchost.exeプロセスとして実行される WaaSMedicSvcサービスに実装されています。Forshaw氏の優れた解説は、私たちの概念実証のファイルレス横移動技術の応用研究および開発の基礎となりました。

ニュースレターを表示しているスマホの画面

The DX Leaders

「The DX Leaders」は日本語でお届けするニュースレターです。AI活用のグローバル・トレンドや日本の市場動向を踏まえたDX、生成AIの最新情報を毎月お届けします。

研究概要

私たちの研究の旅は、IDispatchインターフェースをサポートするWaaSRemediation COMクラスを研究することから始まりました。このインターフェースを使用すると、クライアントは遅延バインディングを実行できます。通常、COMクライアントには、使用しているオブジェクトのインターフェースと型定義がコンパイル時に定義されています。代わりに、遅延バインディングにより、クライアントはランタイムにオブジェクトのメソッドを検出して呼び出すことができます。IDispatchには、ITypeInfo インターフェースを返す GettypeInfoメソッドが含まれています。ITypeInfoには、それを実装するオブジェクトの型情報を検出するために使用できるメソッドがあります。

COMクラスがタイプ・ライブラリーを使用する場合、クライアントはITypeLibITypeInfo-> GetContainingTypeLibから取得)を介してクエリーを実行し、タイプ情報を取得できます。さらに、タイプ・ライブラリーは、追加のタイプ情報を得るために他のタイプ・ライブラリーを参照する場合もあります。

Forshaw氏のブログ投稿によると、WaaSRemediationはタイプ・ライブラリーWaaSRemediationLibを参照し、WaaSRemediationLibはstdole(OLE Automation)を参照しています。WaaSRemediationLibは、そのライブラリーの2つのCOMクラス、StdFontStdPictureを利用します。StdFont オブジェクトの TreatAs レジストリキーを変更して COMハイジャック を行うことで、クラスは.NETフレームワーク内のSystem.Objectなど、私たちが選んだ別のCOMクラスをポイントするようになります。ただし、Forshaw氏は、このオブジェクトがプロセス外のインスタンス化のチェックを実行するため、StdPictureは実行不可能であると指摘しています。そのため、私たちはStdFontの使用に焦点を当てました。

.NETオブジェクトが私たちにとって興味深いのは、 System.ObjectGet Typeメソッドのおかげです。GetTypeを通じて.NETリフレクションを実行し、最終的にAssembly.Loadにアクセスすることができます。System.Objectが選択されましたが、この型は.NETの型階層のルートになります。したがって、任意の.NET COMオブジェクトを使用できます。

初期段階が設定された場合、HKLM\Software\Microsoft\.NetFrameworkキーの下に、認識されたユースケースを実現するために必要な他の2つのDWORD値がありました。

  • AllowDCOMReflection:Forshaw氏が指摘したように、この有効化された値によって、任意の.NETメソッドを呼び出す際に任意のリフレクションを実行できるようになります。通常、.NET Reflection over DCOMは、MS14-009の緩和策により防止されています。
  • OnlyUseLatestCLRProcmonを使ってこの値を有効にして最新の.NET CLR(バージョン4)を読み込む必要があり、そうでなければデフォルトでバージョン2が読み込まれることがわかりました。

最新バージョンのCLRと.NETを初期のテスト作業でロードできることを確認したとき、私たちは正しい道を進んでいることがわかりました。

ローカル・プロセスからリモート・コンピューターへ

リモート プログラムの側面に焦点を当てて、最初にリモート・レジストリーを使用して.NetFrameworkレジストリー・キーの値を操作し、ターゲット・マシン上のStdFontオブジェクトをハイジャックしました。次に、CoCreateInstanceCoCreateInstanceExを入れ替えて、リモート・ターゲットのWaaSRemediationCOMオブジェクトをインスタンス化し、IDispatch インターフェースへのポインターを取得します。

IDispatchへのポインターを使用して、 GetTypeInfoメンバー・メソッドを呼び出して、サーバー内にトラップされているITypeInfoインターフェースへのポインターを取得します。その後呼び出されるメンバー・メソッドはサーバー側で発生します。対象となるタイプ・ライブラリー参照(stdole)を特定し、その後継となるクラス・オブジェクト参照(StdFont)を導出した後、最終的にITypeInfoインターフェースの「リモート可能な」CreateInstanceメソッドを使用して、StdFontオブジェクトのリンクフローを(前のTreatAs操作を介して)リダイレクトしてSystem.Objectをインスタンス化しました。

AllowDCOMReflectionが適切に設定されているため、DCOM上で.NETリフレクションを実行してAssembly.Loadにアクセスし、.NETアセンブリをCOMサーバーにロードすることができます。ここではAssembly.Load over DCOMを使用しているため、アセンブリのバイト転送は DCOM のリモート・マジックによって処理されるため、この横移動手法は完全にファイルレスです。オブジェクトのインスタンス化から反映までのこの技術的フローの詳細な説明については、次の図を参照してください。

System.Object Classのインスタンス化を示すフローチャート
System.Objectクラスのインスタンス化フロー

開発の苦労

最初の主な問題は、IDispatch->InvokeAssembly.Load_3を呼び出すことでした。Invokeは引数のオブジェクト配列をターゲット関数に渡しますが、Load_3は1バイト配列を受け取るAssembly.Loadのオーバーロードです。したがって、バイトのSAFEARRAYを別のVARIANTSAFEARRAYでラップする必要がありました。 – 最初は、単一のSAFEARRAYバイトを渡そうとし続けました。

オブジェクト・バイトの非管理版を作成する方法を示すコード
オブジェクト・バイトの非管理版の作成

もう1つの問題は、適切なAssembly.Loadオーバーロードを見つけることでした。Helper関数は、GetStaticMethod関数を含む、ForshawのCVE-2014-0257コードから取得されました。この関数は、NET reflection over DCOMを使用して、型ポインター、メソッド名、およびそのパラメーター数を指定して静的メソッドを検索します。Assembly.Loadには、1 つの引数を取る 2 つの静的オーバーロードがあります。そのため、ハッカー・ソリューションを使用することになりました。単一の引数を持つLoadの3番目のインスタンスが正しい選択であることに気付きました。

適切なAssembly.Loadオーバーロードを探すために使用されるコード
適切なAssembly.Loadオーバーロードの探索

運用上の課題

この手法で観察された最大の欠点の1つは、生成されたビーコンの有効期間がCOMクライアントに限定される点です。この場合、武器化バイナリ「ForsHops.exe」(優美な名前です)のアプリケーション有効期間が限定されます。そのため、ForsHops.exeがCOM参照をクリーンアップまたは終了すると、リモート・マシンのsvchost.exeの下で実行されていたビーコンも同様に処理されます。私たちは、.NET アセンブリのメイン・スレッドを無期限にハングさせ、別のスレッドでシェルコードを実行し、ForsHops.exe でエクスプロイト・スレッドをハングさせたままにするなど、さまざまな解決策を試しましたが、どれもうまくいきませんでした。

.NETローダーのメインスレッドがハングアップし、シェルコードが別のスレッドで実行される
.NETローダーのメインスレッドがハングアップし、シェルコードが別のスレッドで実行される

現在の状態では、ForsHops.exeはビーコンが終了するまで実行され、その時点でレジストリー操作が削除されます。改善の余地はありますが、それはこれまでのモデルのユーザー向けの課題として使います。

ForShops.exeの実行のデモンストレーション
ForShops.exeの実行
Windows 2019サーバーで成功したビーコン
Windows 2019サーバーで成功したビーコン
PPL svchostプロセスで実行されているビーコンのスクリーンショット
BeaconはPPL svchostプロセスで実行されます
ビーコン終了後に変更を削除するForShops.exeの例
ForShops.exeがビーコン終了後の変更を削除します

防御に関する推奨事項

Mohamed Fakroudが実装を公開した後にSamir Bousseaden(@SBousseaden) が提案した検出ガイダンスは、次の横移動手法にも適用されます。

  • WaaSMedicSvcsvchost.exeプロセス内でCLRロード・イベントを検出
  • 以下のキーのレジストリー操作(または作成)を検出: HKLM\SOFTWARE\Classes\CLSID\{0BE35203-8F91-11CE-9DE3-00AA004BB851} \TreatAs( StandardFont CLSIDの TreatAsキー)

さらに、次の追加の制御を実装することをお勧めします。

  • HKLM\SOFTWARE\Classes\CLSID\{0BE35203-8F91-11CE-9DE3-00AA004BB851}のDACL操作検出
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework有効になっているOnlyUseLatestCLRAllowDCOMReflectionの値が存在するかどうかを確認します。
  • ホストベースのファイアウォールを有効にしてDCOM一時ポートへのアクセスを可能な限り制限する

さらに、概念実証の次のYARAルールを利用して、標準のForsHops.exe実行可能ファイルを検出します。

ルール Detect_Standard_ForsHops_PE_By_Hash

{
    meta:   
        description = "Detects the standard ForShops PE file by strings"
        reference = "GitHub Project: https://github.com/xforcered/ForsHops/"
    strings:
        $s1 = "System.Reflection.Assembly, mscorlib" wide
        $s2 = "{72566E27-1ABB-4EB3-B4F0-EB431CB1CB32}" wide
        $s3 = "{34050212-8AEB-416D-AB76-1E45521DB615}" wide
        $s4 = "GetType" wide
        $s5 = "Load" wide

    condition:
        all of them
}

まとめ

私たちの実装は、PPLバイパスのローカル実行ではなく、トラップされたCOMオブジェクトを横移動に利用することにより、Forshaw氏のブログで説明されているCOM悪用をわずかに拡張します。したがって、ローカル実行の実装と同じ検出の影響を受けます。

ForsHops.exeの概念実証の横移動コードはこちらでご覧いただけます。

謝辞

この研究に対するフィードバックとブログ記事のレビューを提供してくださったDwight Hohnstein(@djhohnstein)とSanjiv Kawa(@sanjivkawa)に特別な感謝を申し上げます。

参考情報

オフィスでミーティングをするビジネスチーム

IBMお客様事例

お客様のビジネス課題(顧客満足度の向上、営業力強化、コスト削減、業務改善、セキュリティー強化、システム運用管理の改善、グローバル展開、社会貢献など)を解決した多岐にわたる事例のご紹介です。

関連ソリューション
エンタープライズ・セキュリティー・ソリューション

世界有数の企業向けセキュリティー・プロバイダーが提供するソリューションで、セキュリティー・プログラムを変革します。

サイバーセキュリティー・ソリューションの詳細
サイバーセキュリティー・コンサルティング・サービス

サイバーセキュリティー・コンサルティングやクラウド、マネージド・セキュリティー・サービスでビジネスを変革し、リスクを管理しましょう。

    サイバーセキュリティー・サービスはこちら
    サイバーセキュリティーのための人工知能(AI)| IBM

    AIを活用したサイバーセキュリティー・ソリューションで、セキュリティー・チームの俊敏性、精度、生産性を向上させます。

    AIを活用したサイバーセキュリティーの詳細はこちら
    次のステップ

    データ・セキュリティー、エンドポイント管理、IDおよびアクセス管理(IAM)ソリューションのいずれが必要であっても、IBMのエキスパートはお客様と協力して、高度なセキュリティー体制を実現します。サイバーセキュリティー・コンサルティング、クラウド・セキュリティー・サービス、マネージド・セキュリティー・サービスなど、業界の世界的リーダーとして、事業の変革とリスク管理を支援します。

    サイバーセキュリティー・ソリューションの詳細 サイバーセキュリティー・サービスを発見する