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

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

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

Forshaw氏の研究に基づいて、Mohamed Fakroud氏(@T3nb3w)は2025年3月初旬に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バイパスのユースケースについて説明しています。WaaSRemediationWaaSMedicSvcサービスに実装されており、NT AUTHORITY\SYSTEMのコンテキストで、保護されたsvchost.exeプロセスとして実行されます。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を利用します。TreatAsレジストリキーを変更してStdFontオブジェクトでCOMハイジャックを実行することで、クラスは.NET Framework内のSystem.Objectなど、選択した別のCOMクラスを指し示します。ただし、Forshaw氏は、このオブジェクトがプロセス外のインスタンス化のチェックを実行するため、StdPictureは実行不可能であると指摘しています。そのため、私たちはStdFontの使用に引き続き焦点を当てました。

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

初期段階が設定されると、想定されるユースケースを現実のものにするために必要なHKLM\Software\Microsoft\.NetFrameworkキーの下に次の2つのDWORD値が追加されました。

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

最初のテスト作業でCLRと.NETの最新バージョンをロードできることを確認したところ、順調に進んでいることがわかりました。

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

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

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

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

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

開発の苦労

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

Object Byteと同等のアンマネージド・オブジェクトを作成する方法を示すコード
Object Byteと同等のアンマネージド版の作成

もう1つの問題は、適切なAssures.Loadのオーバーロードを見つけることでした。ヘルパー関数は、GetStaticMethod関数を含む、Forshaw氏のCVE-2014-0257コードから取得されました。この関数は、DCOM上の.NETリフレクションを使用して、型ポインター、メソッド名、およびそのパラメーター数が与えられた静的メソッドを検索します。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プロセスで実行されているBeacon
ビーコン終了後に変更を削除するForShops.exeの例
ビーコン終了後の変更を削除するForShops.exe

防御の推奨事項

Mohamed Fakroud氏が実装を公開した後にSamir Bousseaden氏(@SBousseaden)が提案した検知ガイダンスも、この横移動技術に適用されます。

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

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

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

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

rule 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
}

まとめ

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

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

謝辞

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

参考情報

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

IBMお客様事例

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

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

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

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

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

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

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

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

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

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