FoggyWeb: 標的を絞った NOBELIUM マルウェアが永続的なバックドアにつながる

news

マイクロソフトは引き続きパートナーやお客様と協力して、 SUNBURST バックドア、TEARDROP マルウェア、および関連コンポーネントの背後にいる攻撃者である NOBELIUM と呼ばれる脅威アクターを追跡し、知識を広げています。前に述べたように、NOBELIUM は、特注のマルウェアやツールなど、キャンペーンでよく紹介される重要な運用リソースを利用できるのではないかと考えています。 2021 年 3 月、私たちは NOBELIUM のGoldMax、GoldFinder、Sibot マルウェアのプロファイルを作成しました。その後、5 月に別の投稿を行い、EnvyScout、BoomBox、NativeZone、および VaporRage で構成される攻撃者の初期段階のツールセットを分析しました。

このブログは、新たに検出された NOBELIUM マルウェアの別の詳細な分析です。NOBELIUM は、Microsoft Threat Intelligence Center (MSTIC) がFoggyWebと呼んでいるエクスプロイト後のバックドアです。以前のブログで述べたように、NOBELIUM は、Active Directory フェデレーション サービス ( AD FS ) サーバーへの管理者レベルのアクセス権を取得することを目的として、複数の戦術を採用して資格情報の盗難を追求しています。 NOBELIUM が資格情報を取得し、サーバーへの侵入に成功すると、アクターはそのアクセスを利用して永続性を維持し、洗練されたマルウェアやツールを使用して侵入を深めます。 NOBELIUM は、FoggyWeb を使用して、侵害された AD FS サーバーの構成データベース、復号化されたトークン署名証明書、およびトークン復号化証明書をリモートで盗み出し、追加のコンポーネントをダウンロードして実行します。 FoggyWeb の使用は、2021 年 4 月には実環境で確認されています。

マイクロソフトは、この活動によって標的にされたり侵害されたりしたことが確認されたすべてのお客様に通知しました。組織が侵害されたと思われる場合は、次のことをお勧めします。

  • 構成、ユーザーごとおよびアプリごとの設定、転送ルール、アクターがアクセスを維持するために行った可能性のあるその他の変更など、オンプレミスおよびクラウド インフラストラクチャを監査します。
  • ユーザーとアプリのアクセスを削除し、それぞれの構成を確認して、文書化された業界のベスト プラクティスに従って新しい強力な資格情報を再発行します。
  • AD FS サーバーをセキュリティで保護するで説明されているように、 ハードウェア セキュリティ モジュール (HSM)を使用して、FoggyWeb によるシークレットの流出を防ぎます。

マイクロソフトのセキュリティ製品には、このマルウェアに対する検出と保護が実装されています。 Azure Sentinel および Microsoft 365 Defender のお客様向けの侵害の兆候 (IOC)軽減策のガイダンス検出の詳細、およびハンティング クエリは、この分析の最後と製品ポータルで提供されます。 Active Directory フェデレーション サービス ( AD FS ) サーバーはオンプレミスで実行され、顧客はAD FS サーバーを攻撃から保護するための詳細なガイダンスに従うこともできます。

FoggyWeb: AD FS を標的とするバックドア

FoggyWeb は、侵害された AD FS サーバーから機密情報をリモートで盗み出すことができる、高度に標的を絞った受動的なバックドアです。また、コマンド アンド コントロール (C2) サーバーから追加の悪意のあるコンポーネントを受信し、侵害されたサーバーでそれらを実行することもできます。

AD FS サーバーを侵害した後、NOBELIUM がシステムに次の 2 つのファイルをドロップすることが確認されました (これらのファイルを以下にリストされているフォルダーに書き込むには、管理者権限が必要です)。

  • %WinDir%ADFSversion.dll
  • %WinDir%SystemResourcesWindows.Data.TimeZonesprisWindows.Data.TimeZones.zh-PH.pri

FoggyWeb は、暗号化されたファイルWindows.Data.TimeZones.zh-PH.priに格納されていますが、悪意のあるファイルversion.dllはそのローダーとして記述できます。 AD FS サービスの実行可能ファイルであるMicrosoft.IdentityServer.ServiceHost.exeは、コアの共通言語ランタイム (CLR) DLL ファイル (FoggyWeb ローダー セクションで詳しく説明) を含むDLL 検索順序ハイジャック手法を使用して、上記の DLL ファイルを読み込みます。このローダーは、暗号化された FoggyWeb バックドア ファイルをロードし、カスタムの軽量暗号化アルゴリズム (LEA) ルーチンを利用してメモリ内のバックドアを復号化します。

バックドアの難読化を解除した後、ローダーは AD FS アプリケーションの実行コンテキストで FoggyWeb を読み込みます。アンマネージド アプリケーションであるローダーは、CLR ホスティング インターフェイスと API を利用して、正規の AD FS マネージド コードが実行されるのと同じアプリケーション ドメインに、マネージド DLL であるバックドアを読み込みます。これにより、AD FS 構成データベースを含む AD FS コードベースとリソースへのバックドア アクセスが許可されます (構成データベースへのアクセスに必要な AD FS サービス アカウントのアクセス許可を継承するため)。

version.dll を読み込んだ後の Microsoft.IdentityServer.ServiceHost.exe の構造を示す図

FoggyWeb バックドア (開発者によって当初はMicrosoft.IdentityServer.WebExtension.dllという名前でした) は、読み込まれると、Security Assertion Markup Language (SAML) トークンの悪用を可能にする、受動的で永続的なバックドアとして機能します。バックドアは、ターゲットの AD FS 展開で使用される正当な URI の構造を模倣する、攻撃者が定義した URI の HTTP リスナーを構成します。カスタム リスナーは、イントラネット/インターネットから AD FS サーバーに送信されるすべての受信 HTTP GET および POST 要求を受動的に監視し、アクターによって定義されたカスタム URI パターンに一致する HTTP 要求をインターセプトします。このバージョンの FoggyWeb は、次のハードコードされた URI パターン (ターゲットごとに異なる場合があります) のリスナーを構成します。

  • HTTP GET URI パターン:
    • /adfs/portal/images/theme/light01/profile.webp
    • /adfs/portal/images/theme/light01/background.webp
    • /adfs/portal/images/theme/light01/logo.webp
  • HTTP POST URI パターン:
    • /adfs/services/trust/2005/samlmixed/upload

上記の各 HTTP GET/POST URI パターンは、C2 コマンドに対応しています。

  • AD FS サーバーが URI パターン/adfs/portal/images/theme/light01/profile.webpを含む HTTP GET 要求を受信すると、バックドアは侵害された AD FS サーバーのトークン署名証明書を取得し、難読化して証明書をリクエストの発行者。
  • 同様に、AD FS サーバーが URI パターン/adfs/portal/images/theme/light01/background.webpを含む HTTP GET 要求を受信すると、バックドアは侵害された AD FS サーバーのトークン復号化証明書を取得し、難読化して、要求の発行者への証明書。
  • AD FS サーバーが URI パターン/adfs/portal/images/theme/light01/logo.webpを含む HTTP GET 要求を受信すると、バックドアは侵害されたサーバーの AD FS 構成データを取得し、データを難読化し、難読化されたファイルを返します。データをリクエストの発行者に送信します。
  • AD FS サーバーが URI パターン/adfs/services/trust/2005/samlmixed/uploadを含む HTTP POST 要求を受信すると、バックドアは難読化および圧縮された POST データを .NET アセンブリまたはソース コードとして扱います。アセンブリの場合、バックドアは AD FS プロセスの実行コンテキストでアセンブリを実行します。ソース コードの場合、バックドアはソース コードを動的にコンパイルし、AD FS プロセスの実行コンテキストで結果のメモリ常駐アセンブリを実行します。

以下の図は、侵害されたインターネットに接続された AD FS サーバー上にある FoggyWeb バックドアと通信するためにアクターが使用する方法を示しています。

FoggyWeb 攻撃チェーンを示す図

FoggyWeb はメインの AD FS プロセスのコンテキストで実行されるため、AD FS 構成データベースへのアクセスに必要な AD FS サービス アカウントのアクセス許可を継承します。これは、AD FS サービス アカウントのユーザー コンテキストで実行する必要があるADFSDumpなどのツールとは対照的です。また、FoggyWeb は AD FS マネージ コードと同じアプリケーション ドメインに読み込まれるため、正規の AD FS クラス、メソッド、プロパティ、フィールド、オブジェクト、およびコンポーネントへのプログラムによるアクセスを取得し、その後 FoggyWeb によって悪意のある操作を容易にするために利用されます。 .たとえば、これにより、FoggyWeb は、WID 名前付きパイプに接続したり、SQL クエリを手動で実行して構成情報を取得したり (構成データからEncryptedPfx BLOB を取得するなど) しなくても、AD FS 構成データにアクセスできます。また、FoggyWeb は AD FS のバージョンに依存しません。従来と最新の構成テーブル名とスキーマ、名前付きパイプ名、AD FS のその他のバージョン依存プロパティを追跡する必要はありません。

FoggyWeb ローダー

ファイルversion.dllは、暗号化されたバックドア ファイルをファイル システムからロードし、バックドア ファイルを復号化し、メモリにロードする悪意のあるローダーです。 %WinDir%System32フォルダーにある正規の Windows DLL と名前を共有するこの悪意のある DLL は、メインの AD FS フォルダー%WinDir%ADFSに配置されることを意図しています。 IdentityServer.ServiceHost.exeが配置されています (理由については、このセクションで後述します)。

AD FS サービス ( adfssrv ) が開始されると、サービスの実行可能ファイルMicrosoft.IdentityServer.ServiceHost.exeが実行されます。 .NET ベースのマネージド アプリケーションであるMicrosoft.IdentityServer.ServiceHost.exeは、 mscoree.dllというアンマネージド Windows DLL をインポートします。

mscoree.dll をインポートする Microsoft.IdentityServer.ServiceHost.exe を示すスクリーンショット。

ファイルmscoree.dllは、 mscoreei.dllという別の管理されていない Windows/CLR DLL を動的に読み込みます。以下に示すように、 mscoreei.dllにはversion.dllという名前の遅延ロード インポート (遅延インポート) があります。

mscoreei.dll に version.dll という名前の遅延ロード インポート (遅延インポート) があることを示すスクリーンショット

既存の管理権限を持つ NOBELIUM は、AD FS サービスの実行可能ファイルMicrosoft.IdentityServer.ServiceHost.exeがある%WinDir%ADFSフォルダに、 version.dllという名前の悪意のあるローダーをドロップすることが確認されました。システムまたは AD FS サービスが再起動されると、 Microsoft.IdentityServer.ServiceHost.exeによって mscoree.dllが読み込まれ、さらにmscoreei.dllが読み込まれます。前述のように、 mscoreei.dllにはversion.dllという名前の遅延ロード インポートがあります。読み込まれると、 %WinDir%System32フォルダーから正規のversion.dllを読み込む代わりに、 mscoreei.dllが攻撃者によって%WinDir%ADFSフォルダーに埋め込まれた悪意のあるversion.dllを読み込みます ( DLL 検索順序ハイジャックと呼ばれます)。 、以下のコール スタックに示すように。

フォルダ mscoreei.dll が攻撃者によって %WinDir%ADFS フォルダに埋め込まれた悪意のある version.dll をロードすることを示すコール スタックのスクリーンショット

悪意のあるローダーversion.dllは、すべての正当なversion.dllエクスポート関数呼び出しのプロキシとして動作します。以下に示すように、正規バージョンのversion.dllと同じ 17 個の関数名をエクスポートします。

正当な version.dll のダンプのスクリーンショット悪意のある version.dll のスクリーンショット

以下のスクリーンショットに示すように、悪意のあるversion.dllのエクスポート関数はすべて、 TrampolineFunctionというラベルの付いた単一のトランポリン関数を呼び出す短いスタブです。

悪意のある version.dll のエクスポート機能のスクリーンショット

以下はトランポリン関数の擬似コードです。

トランポリン機能の疑似コードのスクリーンショット

このトランポリン機能は、次の役割を果たします。

  • 関数 (アナリストによってLoadDecryptExecuteBackdoor()とラベル付けされている) を呼び出して、ファイル システムからバックドア ファイルをロードし、メモリ内のファイルを復号化して実行する
  • version.dllの正当なバージョンから、最初に呼び出されたターゲット関数に実行を転送します。

トランポリン関数は、特定の CPU レジスタの値を保存することにより、 version.dllの正当なバージョンから関数用の引数/レジスタの値を保存します。上記のLoadDecryptExecuteBackdoor()関数を呼び出す前にまずそれらをスタックにプッシュし、次にそれらを復元してから、正規バージョンのversion.dllから関数に実行を転送します。

トランポリン関数を示すコードのスクリーンショットは、特定の CPU レジスタの値を保存することにより、version.dll の正当なバージョンから関数用の引数/レジスタの値を保存します。

LoadDecryptExecuteBackdoor()が呼び出されると、 {2783c149-77a7-5e51-0d83-ac0566daff96}という名前の Windows イベントを作成して、ローダーのコピーが 1 つだけシステム上でアクティブに実行されるようにします。新しいスレッドで、次のファイルが存在するかどうかを確認します (ハードコードされたパス文字列)。

C:WindowsSystemResourcesWindows.Data.TimeZonesprisWindows.Data.TimeZones.zh-PH.pri

Windows.Data.TimeZones.zh-PH.priは暗号化されたバックドア ファイルで、上記のフォルダーに配置されています。 MSTIC はこのバックドア ファイルを FoggyWeb と呼んでおり、その分析は次のセクションで行います。

Microsoft.IdentityServer.ServiceHost.exe自体は、高レベルの AD FS マネージ コードがコンパイルされるときに生成されるアンマネージ Windows 実行可能ファイルです。実行されると、 Microsoft.IdentityServer.ServiceHost.exe内のアンマネージド コードは、共通言語ランタイム (CLR) を利用して、仮想ランタイム環境内でマネージド AD FS コードを実行します。この仮想ランタイム環境は、1 つ以上のアプリケーション ドメインで構成されます。アプリケーション ドメインは、ランタイム環境の分離単位を提供し、さまざまなアプリケーションをプロセス内の個別のコンテナー内で実行できるようにします。マネージド AD FS コードは、仮想ランタイム環境内のアプリケーション ドメイン内で実行されます。

FoggyWeb バックドア (マネージ DLL) は、正当な AD FS コードと一緒に (つまり、同じアプリケーション ドメイン内で) 実行することを目的としています。これは、FoggyWeb ローダーが AD FS コードと一緒にバックドアを読み込むには、AD FS コードが実行されているのと同じアプリケーション ドメインにアクセスする必要があることを意味します。 FoggyWeb ローダーversion.dllはアンマネージド アプリケーションであるため、マネージド AD FS コードが実行される仮想ランタイム環境に直接アクセスすることはできません。ローダーはこの制限を克服し、CLR ホスティング インターフェイスと API を利用して AD FS コードが実行される仮想ランタイム環境にアクセスすることで、AD FS コードと共にバックドアを読み込みます。

ローダーは、次の高レベルのアクションを実行します。

  • AD FS プロセスに読み込まれたすべての CLR を列挙するMicrosoft.IdentityServer.ServiceHost.exe
  • CLR ごとに、実行中のすべてのアプリケーション ドメインを列挙し、ドメインごとに次のアクションを実行します。
    • 次の暗号化された FoggyWeb バックドア ファイルの内容をメモリに読み取ります: C:WindowsSystemResourcesWindows.Data.TimeZonesprisWindows.Data.TimeZones.zh-PH.pri
    • Lightweight Encryption Algorithm (LEA) を使用して、暗号化された FoggyWeb バックドア ファイルを復号化します。 LEA-128 キー スケジュールは、次のハードコードされたマスター キーを使用してラウンド キーを生成します。

ラウンド キーを生成するためのハードコードされたマスター キーのスクリーンショット

各 16 バイトの暗号ブロックを復号化した後、ローダーは次の XOR キーを使用して、個々の復号化された/平文ブロックを復号化します。

個々の復号化された/平文ブロックをデコードするための XOR キーのスクリーンショット

これは、最初にファイル全体を LEA 復号化してから、復号化されたデータを XOR 復号化することと同じです (個々の 16 バイト ブロックを復号化して XOR 復号化する代わりに)。

    • セーフ アレイを作成し、復号化された FoggyWeb バックドア バイトをアレイにコピーします。次に、現在のアプリケーション ドメインのLoad()関数を呼び出して、FoggyWeb DLL をアプリケーション ドメインにロードします。 FoggyWeb DLL が現在のアプリケーション ドメインに読み込まれると、ローダーは DLL から次のメソッドを呼び出します: Microsoft.IdentityServer.WebExtension.WebHost

実行サイクルのこの時点で、FoggyWeb DLL は、正当な AD FS コードが実行されている 1 つ以上のアプリケーション ドメインに読み込まれます。これは、バックドア コードが AD FS アプリケーションと同じアクセス権とアクセス許可で AD FS コードと一緒に実行されることを意味します。バックドアは AD FS コードと同じアプリケーション ドメインに読み込まれるため、さまざまな AD FS モジュールが正当な機能を実行するために使用する正当なクラス、メソッド、プロパティ、フィールド、オブジェクト、およびコンポーネントへのプログラムによるアクセスを取得します。このようなアクセスにより、FoggyWeb バックドアは AD FS コードベース (つまり、外部のディスク常駐ツールではない) と直接対話し、悪意のある操作を容易にするために必要なネイティブ AD FS メソッドを選択的に呼び出すことができます。

FoggyWeb バックドア

この悪意のあるメモリ常駐 DLL (開発者によって元の名前はMicrosoft.IdentityServer.WebExtension.dll ) は、AD FS を標的とするバックドアとして機能します。これは、メインの AD FS サービス プロセスであるMicrosoft.IdentityServer.ServiceHost.exeによって、悪意のあるローダー コンポーネントを介して読み込まれます。

読み込まれると、バックドアは、次の URI パターンを含む HTTP GET および POST リクエストをリッスンする HTTP リスナーを開始します。

  • HTTP GET URI パターン: /adfs/portal/images/theme/light01/
  • HTTP POST URI パターン: /adfs/services/trust/2005/samlmixed/upload

以下に示すように、URI パターンはバックドアでハードコーディングされており、ターゲットの AD FS 展開で使用される正当な URI の構造を模倣しています。

ターゲットの AD FS 展開で使用される正当な URI の構造を模倣するバックドア構造のスクリーンショット。

バックドアが上記の URI パターンのいずれかを含む HTTP リクエストを受信すると、リスナーは HTTP GET または HTTP POST コールバック/ハンドラ メソッド (それぞれProcessGetRequest()およびProcessGetRequest() ) を使用してリクエストを処理します。

HTTP GET または HTTP POST コールバック/ハンドラー メソッドを使用してリクエストを処理するリスナーを示すコードのスクリーンショット

HTTP GET ハンドラー

URI パターン/adfs/portal/images/theme/light01/を含む着信 HTTP GET 要求は、バックドアのProcessGetRequest()メソッドによって処理されます。

ProcessGetRequest() メソッドのスクリーンショット

ファイル拡張子が .webp のファイル/リソースに対して着信 HTTP GET 要求が発行された場合、 ProcessGetRequest ()メソッドは要求の処理に進みます。それ以外の場合、リクエストはバックドアによって無視されます。また、要求されたファイル名が以下の 3 つのハードコードされた名前のいずれかと一致する場合、バックドアはその要求を攻撃者が発行した C2 コマンドとして扱います。

ハードコーディングされた名前を示すコードのスクリーンショット

次の URL パターンは C2 コマンドとして扱われます。

  • /adfs/portal/images/theme/light01/profile.webp
  • /adfs/portal/images/theme/light01/background.webp
  • /adfs/portal/images/theme/light01/logo.webp

最初の 2 つの C2 コマンド、 profile.webpbackground.webp (上のスクリーンショットのUrlGetFileNames[0]UrlGetFileNames[1] ) は、バックドアのService.GetCertificate()メソッドを呼び出すことによって処理されます。

Service.GetCertificate() メソッドのコードのスクリーンショット

名前が示すように、このメソッドは、AD FS サービス構成データベースから AD FS 証明書 (メソッドに渡されたcertificateTypeパラメーターの値に応じて、トークン署名またはトークン暗号化証明書) を取得します。

アナリストのメモ: Service.GetCertificate() メソッドの詳細な分析と、トークン署名または暗号化証明書を取得して復号化する方法については、付録を参照してください

上のスクリーンショットに示すように、C2 コマンドのprofile.webp ( UrlGetFileNames[0] ) がバックドアに対して発行された場合 (URI /adfs/portal/images/theme/light01/profile.webpに対して HTTP GET 要求を発行することによって) 、バックドアは侵害された AD FS サーバーのトークン署名証明書を取得します。同様に、C2 コマンドbackground.webp ( UrlGetFileNames[1] ) がバックドアに発行されると (URI /adfs/portal/images/theme/light01/background.webpに対して HTTP GET 要求を発行することによって)、バックドアは侵害された AD FS サーバーのトークン暗号化証明書

3 番目の C2 コマンドであるlogo.webp ( UrlGetFileNames[2] ) は、HTTP GET 要求を次の URI に送信することによってトリガーされます: /adfs/portal/images/theme/light01/logo.webp 。 C2 コマンドは、バックドアのGetInfo()メソッドを呼び出すことによって処理されます。

バックドアの GetInfo() メソッドのコードのスクリーンショット

GetInfo()メソッドは、侵害されたサーバーの AD FS サービス構成データのダンプを担当します。

AD FS サービス構成データをダンプする GetInfo() メソッドのスクリーンショット

上記のように、AD FS サービス構成データはServiceSettingsDataプロパティを介して取得され、AD FS サービス構成データベースである Windows Internal Database (WID) からデータが取得されます。

C2 コマンドの出力 (つまり、トークン署名証明書、トークン暗号化証明書、または AD FS サービス構成データ) を HTTP 200 応答で C2 に返す前に、バックドアはまずメソッドを呼び出して出力を難読化します。 GetWebpImage()という名前です。

GetWebpImage() メソッドのコードのスクリーンショット

GetWebpImage()メソッドは、(適切な RIFF/WebP ファイル ヘッダー マジック/フィールドを追加することによって) C2 コマンドの出力を正当な WebP ファイルとして偽装し、結果の WebP ファイルをエンコードする役割を担います。

C2 の出力を偽装する GetWebpImage() メソッドのコードのスクリーンショット

GetWebpImage()は、次のヘルパー メソッドを使用して、C2 コマンド出力を含む偽の WebP ファイルを作成およびエンコードします。

  • GetWebpImage()は、最初にWebp.GetFrame()メソッドを呼び出します。このメソッドは、C2 コマンドの出力を圧縮し、圧縮バージョンを新しい配列にコピーします (0 を 32 バイトの倍数に埋め込みます)。圧縮されたデータの長さは、新しい配列の最初の 4 バイトとして追加されます。

最初に Webp.GetFrame() メソッドを呼び出す GetWebpImage() のコードのスクリーンショット

データを圧縮するために、 GetFrame()Common.Compress()メソッドを呼び出します。このメソッドは、C# GZipStream 圧縮クラスを利用してデータを圧縮するために使用されます。

Common.Compress() メソッドを呼び出す GetFrame() のコードのスクリーンショット

デモンストレーションのために、C2 コマンドが次のデータ (疑似ランダムに生成された 256 バイトのバイト配列) を生成すると仮定します。

疑似ランダムに生成された 256 バイトのバイト配列のスクリーンショット

上記のデータ (サンプル C2 コマンド出力) を指定すると、 GetFrame()は次のバイト配列を返します。

GetFrame() によって返されるバイト配列のスクリーンショット

  • 次に、 GetWebpImage()Webp.GetWebpHeader()メソッドを呼び出し、上記の手順でGetFrame()によって返されたバイト配列のサイズを渡します。 GetWebpHeader()は、カスタム RIFF WebP ファイルのマジック/ヘッダー バイトを含む配列を作成して返す役割を果たします。

Webp.GetWebpHeader() メソッドを呼び出す GetWebpImage() のコードのスクリーンショット

上記の配列変数には、次の 32 バイトのハードコードされた RIFF/WebP ヘッダー バイトが含まれています。

32 バイトのハードコーディングされた RIFF/WebP ヘッダー バイトのスクリーンショット

GetWebpHeader()に渡される配列 ( GetFrame()によって返される) のサイズが 8,192 バイトを超える場合、ヘッダー バイト (最初は 0x00 に設定) のインデックス 26 と 28 のバイトが 0x80 に置き換えられます。それ以外の場合、以下に示すように、インデックス 26 と 28 のバイトは 0x40 に置き換えられます。

インデックス 26 と 28 のバイトが 0x40 に置き換えられていることを示すスクリーンショット

 GetWebpHeader()は、上記のカスタム RIFF/WebP ヘッダーをGetWebpImage () に返します。

  • 次に、 GetWebpImage()は、GetWebpHeader() によって返されたカスタム RIFF/WebP ヘッダー バイトを、 GetFrame()によって返された配列 (圧縮されたバージョンの C2 コマンド出力を含む配列) に追加することによって、新しい配列を作成します。

GetWebpImage() を作成する新しい配列のスクリーンショット

GetWebpImage()は、バックドアのCommon.ProtectData()メソッドを呼び出して、圧縮されたバイトを含む新しい配列の部分をエンコードします (つまり、カスタム RIFF/WebP ヘッダーはエンコードしません)。 2 番目の引数として、 GetWebpImage()は最初の圧縮バイトのオフセットをProtectData () に渡します (上記の表に示すように、この場合、0x20 または 32 は最初の圧縮バイトのオフセットです)。 ProtectData()は、動的XOR キーとカスタム XOR 方法論を使用して、圧縮データを XOR エンコードします。

動的 XOR キーとカスタム XOR 手法を使用して圧縮データを XOR エンコードする ProtectData() のコードのスクリーンショット

最初に、12 バイトのハードコードされた XOR キー配列には、次の (シード) バイトが含まれています。

シードバイトのスクリーンショット

上のスクリーンショットに示すように、圧縮されたデータの各バイトは、XOR キー配列のバイトと XOR されます。圧縮データの最初のバイト (0x17) は、キー配列 (0x77) のオフセット 8 にある XOR キー バイトと XOR されます。

圧縮データの最初のバイトを示すスクリーンショット

圧縮データの最初のバイトを、キー配列のオフセット 8 にある XOR キー バイトで XOR した後、XOR キー バイト自体が新しい値で上書きされます。

新しい値で上書きされた XOR キー バイトのスクリーンショット

たとえば、XOR キー配列 (0x77) のオフセット 8 にある XOR キー バイトは、次の操作によって 0xEE で上書きされます。

0xEE で上書きされた XOR キー配列 (0x77) のオフセット 8 にある XOR キー バイトのスクリーンショット

圧縮データの 2 番目のバイト (0x01) は、キー配列のオフセット 9 にある XOR キー バイト ( 33 % 12 = 9 ) と XOR され、キーが XOR 配列の最初のバイト (前述のように、XOR キーのバイトは各エンコード操作の後に上書きされます)。以下は、サンプル圧縮配列の XOR エンコード バージョンです。

圧縮データの 2 バイト目のスクリーンショット

上記の手順の後、 GetWebpImage()は次のサンプル データをメソッドに返します。メソッドはそれを呼び出して、各 C2 コマンド ( ProcessGetRequest() ) の出力を難読化および隠蔽します。

前述のように、 ProcessGetRequest()は、上記で生成された偽の RIFF/WebP ファイル (盗まれたトークン署名証明書、トークン暗号化証明書、または AD FS サービス構成データを含む) を HTTP 200 応答で C2 に返します。

HTTP 200 レスポンスで偽の RIFF/WebP ファイルを C2 に返す ProcessGetRequest() のコードのスクリーンショット

バックドアが C2 コマンドを正常に実行できない場合、代わりに HTTP 404 応答を C2 に返します。

HTTP POST ハンドラ

URI パターン/adfs/services/trust/2005/samlmixed/uploadに一致する着信 HTTP POST 要求は、 ProcessPostRequest()メソッドによって処理されます。

ProcessPostRequest() メソッドのコードのスクリーンショット

このメソッドは、着信 HTTP POST 要求のContentType値が「xml」(大文字と小文字を区別しない) で終わり、HTTP POST データにX509CertificateSignatureValueという名前の 2 つの XML 要素が含まれていることを確認します (たとえば、文字列「 < X509Certificate> 」であり、文字列 </X509Certificate> 」で終わります)。

着信 HTTP POST 要求の ContentType 値が「xml」で終わることを確認する ProcessPostRequest() メソッドのスクリーンショット

XML データに 2 つの要素が含まれている場合、バックドアは次のアクションを実行します。

  • 最初に Base64 を使用して値をデコードし、次にデコードされた各値に対してCommon.UprotectData()メソッドを呼び出して、 SignatureValue要素とX509Certificate要素の値をデコードします。

SignatureValue 要素と X509Certificate 要素の値をデコードするためのコードのスクリーンショット

UprotectData()メソッドは、Base64 でデコードされた値の最初の 2 バイトを 2 バイトの XOR キーとして扱います。残りのデータ (つまり、3 番目のバイト) に対して Common.ProtectData()メソッド (前のセクションで説明) を呼び出し、Common.ProtectData (によって返されたデータを XOR デコードするために 2 バイトの XOR キーを使用します。 。つまり、 UprotectData()Common.ProtectData()を利用して XOR エンコーディングの最初のレイヤーを削除し、次に別の XOR ルーチンを使用して、データに適用された XOR エンコーディングの 2 番目のレイヤーを削除します。

Common.ProtectData() を利用して XOR エンコーディングの最初のレイヤーを削除し、次に別の XOR ルーチンを削除する UprotectData() のコードのスクリーンショット

  • Service.ExecuteAssembly()メソッドを呼び出して、デコードされたSignatureValueおよびX509Certificate値を処理します。以下に示すように、デコードされたX509Certificate値は、 Common.Decompress()メソッドを呼び出すことによって解凍/膨張された最初の GZip です。

デコードされた X509Certificate 値のスクリーンショット。Common.Decompress() メソッドを呼び出すことによって解凍/膨張された最初の GZip

新しいスレッドでは、 Service.ExecuteAssembly()Service.ExecuteAssemblyRoutine()メソッドを呼び出してデータを処理します。

Service.ExecuteAssembly() メソッドを呼び出す Service.ExecuteAssembly() のスクリーンショット

  • ExecuteAssemblyRoutine()は、デコードされたX509Certificate値が「MZ」 (またはバイト0x4D 0x5A 、10 進数77および90の 16 進数表現、以下のスクリーンショットに見られる) で始まるかどうかをチェックします。

「MZ」またはバイト 0x4D 0x5A (10 進数 77 と 90 の 16 進数表現) で始まるデコードされた X509Certificate 値を示すスクリーンショット

  • デコードされたX509Certificateの値が「MZ」で始まる場合、バックドアはデコードされたデータを .NET ベースのアセンブリ/ペイロードとして扱い、 Service.ExecuteBinary()メソッドを呼び出して DLL ペイロードをメモリにロードして実行します。メモリに DLL をロードした後、 ExecuteBinary()は、ロードされた DLL から特定のメソッドを呼び出します。メソッドを呼び出すために必要なメソッド名とパラメータは、デコードされたSignatureValueデータ内でバックドアに提供されます。

DLL ペイロードをメモリにロードして実行する Service.ExecuteBinary() メソッドのコードのスクリーンショット

デコードされたX509Certificate値が MZ で始まらない場合、バックドアはデコードされたX509Certificate値を C# ベースのペイロードのソース コードとして扱い、そのService.ExecuteSource()メソッドを呼び出してメモリ内のペイロードを動的にコンパイルおよび実行します。

メモリ内のペイロードを動的にコンパイルして実行する Service.ExecuteSource() メソッドのコードのスクリーンショット

XML 要素X509CertificateSignatureValueを含む HTTP POST リクエストを処理した後、バックドアは HTTP 204 レスポンス コードでリクエストに応答します。 HTTP POST に上記の要素がない場合、バックドアは HTTP 404 応答コードで要求に応答します。

付録: AD FS トークンの取得と暗号化解除

名前が示すように、 Service.GetCertificate()メソッドは、AD FS サービスから AD FS 証明書 (メソッドに渡されたcertificateTypeパラメーターの値に応じて、トークン署名またはトークン暗号化証明書) を取得する役割を果たします。構成データベース。

AD FS 証明書の取得を担当する Service.GetCertificate() メソッドのコードのスクリーンショット

このメソッドは、次のアクションを実行して、目的の証明書を取得します。

  • GetServiceSettingsDataProvider()という名前の別のメソッドを呼び出して、既に読み込まれているアセンブリMicrosoft.IdentityServerから Microsoft.IdentityServer.PolicyModel.Configuration.ServiceSettingsDataProvider 型のインスタンスを作成します

GetServiceSettingsDataProvider() メソッドを呼び出すコードのスクリーンショット

GetServiceSettingsDataProvider() メソッドのコードのスクリーンショット

  • 上記のServiceSettingsDataProviderインスタンスのGetServiceSettings()メンバー/メソッドを呼び出して、AD FS サービス構成設定を取得します。

GetServiceSettings() メソッドを呼び出すコードのスクリーンショット

  • AD FS サービス設定の値を ( SecurityTokenServiceプロパティから) 取得し、サービス設定からEncryptedPfx BLOB の値を抽出し、Base64 を使用して BLOB をデコードします。

EncryptedPfx BLOB の値を抽出するためのコードのスクリーンショット

  • GetAssemblyByName()という名前の別のメソッドを呼び出して、読み込まれたすべてのアセンブリを名前で列挙し、既に読み込まれているアセンブリMicrosoft.IdentityServer.Serviceを見つけます。このメソッドは、 Microsoft.IdentityServer.Service.Configuration.AdministrationServiceState型のオブジェクト ( Microsoft.IdentityServer.Serviceアセンブリから) から、 _stateおよび_certificateProtectorという名前の 2 つのフィールドの値を取得します。

AdministrationServiceStateクラス/オブジェクトには、クライアント要求の実行と処理に必要な構成情報が含まれています。フィールド_stateは、 AdministrationServiceStateクラス/オブジェクトの現在の状態を維持するために使用されます ( Microsoft.IdentityServer.Service.dllのスクリーンショット)。

AdministrationServiceStateオブジェクト ( _stateフィールドに格納) には、 _certificateProtectorという名前の別のフィールドが含まれています。

フィールド_certificateProtectorには、分散キー管理 (DKM) 用の Data Protector クラスDkmDataProtectorのインスタンスが格納されます。 DkmDataProtectorクラスは Unprotect ()という名前のメソッドを実装し、最終的に DKM/IDKM の Unprotect( )メソッドを呼び出します ( Microsoft.IdentityServer.dllのスクリーンショット)。

DKM Unprotect()メソッドは、 Microsoft.IdentityServer.Dkm.DKMBaseからUnprotect()という名前のメソッドを継承します ( Microsoft.IdentityServer.Dkm.dllのスクリーンショット)。

Microsoft.IdentityServer.Dkm.DKMBaseUnprotect()メソッド (上記参照) は、 EncryptedPfx BLOB に格納されている暗号化された証明書 (PKCS12 オブジェクト) を復号化する機能を提供します。

_certificateProtectorフィールドを介してアクセスできる Unprotect ()メソッドの可用性に関する知識を備えたバックドアは、 Unprotect ()メソッドを呼び出して、目的の証明書タイプ (AD FS トークン署名または暗号化証明書)。

この付録で説明されている手法の変形は、2019 年の TROOPERS カンファレンスで Douglas Bienstock と Austin Baker によって公開されました (私は AD FS であり、あなたもできます: Active Directory フェデレーション サービスを攻撃する)。ただし、FoggyWeb で使用される方法は、公開されている方法とは異なります。FoggyWeb は、 AdministrationServiceStateクラス/オブジェクトの_stateおよび_certificateProtectorフィールドを利用して、Data Protector クラスDkmDataProtector (Unprotect( )へのアクセスと呼び出しに使用) へのアクセスを容易にします。方法)。

侵害の痕跡 (IOC)

タイプ 脅威名 脅威の種類 インジケータ
MD5 フォギーウェブ ローダ 5d5a1b4fafaf0451151d552d8eeb73ec
SHA-1 フォギーウェブ ローダ c896ece073dd01191cbc1d462bc2f47161828a83
SHA-256 フォギーウェブ ローダ 231b5517b583de102cde59630c3bf938155d17037162f663874e4662af2481b1
MD5 フォギーウェブ バックドア (暗号化) 9ff9401315d0f7258a9fcde0cfdef02b
SHA-1 フォギーウェブ バックドア (暗号化) 4597431f26424cb814c917168fa8d74d01ab7cd1
SHA-256 フォギーウェブ バックドア (暗号化) da0be762bb785085d36aec80ef1697e25fb15414514768b3bcaf798dd9c9b169
MD5 フォギーウェブ バックドア (復号化) e9671d294ce41fe6dbb9637dc0157a88
SHA-1 フォギーウェブ バックドア (復号化) 85cfeccbb48fd9f498d24711c66e458e0a80cc90
SHA-256 フォギーウェブ バックドア (復号化) 568392bd815de9b677788addfc4fa4b0a5847464b9208d2093a8623bbecd81e6

緩和策

お客様は、AD FS サーバーの構成を確認し、これらのシステムを攻撃から保護するための変更を実装する必要があります。

組織には、次のベスト プラクティスに従って AD FS 展開を強化し、保護することを強くお勧めします。

  • Active Directory 管理者と AD FS 管理者のみが AD FS システムに対する管理者権限を持っていることを確認します。
  • すべての AD FS サーバーで、ローカル管理者のグループ メンバーシップを減らします。
  • すべてのクラウド管理者に多要素認証 (MFA) の使用を要求します。
  • エージェントによる最小限の管理機能を確保します。
  • ホスト ファイアウォールを介してネットワーク上のアクセスを制限します。
  • AD FS 管理者が管理ワークステーションを使用して資格情報を保護していることを確認します。
  • AD FS サーバー コンピューター オブジェクトを、他のサーバーもホストしない最上位の OU に配置します。
  • AD FS サーバーに適用されるすべての GPO が、AD FS サーバーにのみ適用され、他のサーバーには適用されないことを確認します。これにより、GPO の変更による特権昇格の可能性が制限されます。
  • インストールされた証明書が盗難から保護されていることを確認してください。これらをネットワーク上の共有に保存せず、有効期限が切れる前に確実に更新されるようにカレンダーのリマインダーを設定しないでください (期限切れの証明書はフェデレーション認証を壊します)。さらに、AD FS に接続されたハードウェア セキュリティ モジュール (HSM)で署名キーまたは証明書を保護することをお勧めします。
  • ログ記録を最高レベルに設定し、AD FS (およびセキュリティ) ログを SIEM に送信して、AD 認証および Azure AD (または類似のもの) と関連付けます。
  • 不要なプロトコルと Windows 機能を削除します。
  • AD FS サービス アカウントには、長く (25 文字を超える) 複雑なパスワードを使用します。 グループ管理サービス アカウント (gMSA)をサービス アカウントとして使用することをお勧めします。これにより、サービス アカウントのパスワードが自動的に管理されるため、長期にわたって管理する必要がなくなります。
  • セキュリティとログ記録を改善するために、最新の AD FS バージョンに更新します (いつものように、最初にテストしてください)。
  • Azure AD とフェデレーションする場合は、Azure AD で AD FS の信頼を保護および監視するためのベスト プラクティスに従います。

検出

AD FS サーバーを保護することは、NOBELIUM 攻撃を軽減するための鍵です。 AD FS サーバー上のマルウェア、攻撃者のアクティビティ、およびその他の悪意のあるアーティファクトを検出してブロックすると、既知の NOBELIUM 攻撃チェーンの重要なステップを破ることができます。 Microsoft Defender ウイルス対策は、このブログで説明されている新しい NOBELIUM コンポーネントを次のマルウェアとして検出します。

  • ローダー: Trojan:Win32/FoggyWeb.A!dha
  • バックドア: Trojan:MSIL/FoggyWeb.A!dha

Microsoft 365 ディフェンダー

Microsoft Defender for Endpoint のエンドポイントの検出と応答 (EDR) 機能は、次のタイトルのアラートとして表示されるこのマルウェアに関連する悪意のある動作を検出します。

  • 疑わしい DLL が ADFS サービスによって読み込まれました
  • 不審なサービスが開始されました
  • 疑わしいファイルがドロップされました

Azure AD ID 保護

この種の攻撃は、Azure AD Identity Protection を使用してクラウドでも検出できます。 「トークン発行者の異常」の検出について、 Azure AD Identity Protectionリスク検出レポートを監視することをお勧めします。この検出は、Azure AD テナントに提示された SAML トークンの異常を探します。

高度なハンティング クエリ

エンドポイントの Microsoft Defender

関連するアクティビティを見つけるには、 Microsoft 365 Defender で次の高度な検索クエリを実行します。

DeviceImageLoadEvents
| where FolderPath has @"C:WindowsADFS"
| where FileName has @"version.dll"

アズールセンチネル

Azure Sentinel のお客様は、次の検出クエリを使用して、このアクティビティを探すことができます。

検出クエリ: https://github.com/Azure/Azure-Sentinel/tree/master/Detections/MultipleDataSources/Nobelium_FoggyWeb.yaml

インジケーター ファイル: https://github.com/Azure/Azure-Sentinel/tree/master/Sample%20Data/Feeds/FoggyWebIOC.csv

 

参照: https://www.microsoft.com/en-us/security/blog/2021/09/27/foggyweb-targeted-nobelium-malware-leads-to-persistent-backdoor/

Comments

Copied title and URL