エグゼクティブサマリー
Rubrik Zero LabsのAI支援型マルウェア解析パイプラインは最近、「GhostChrome-X」と名付けられた新たな脅威を特定しました。認証情報の窃取やセッションハイジャックを主眼とする従来型のブラウザベースマルウェアとは異なり、GhostChrome-XはChromeブラウザを通じたアクセスの確立と維持において、より高度な手法を採用しています。
GhostChrome-Xが特に注目される点は2つあります。第一に、このマルウェアは保護された設定ファイルを改変し、Chromeが攻撃者制御下の拡張機能を正規のブラウザコンポーネントとして受け入れるために必要な整合性メタデータを偽造することで、Chromeの拡張機能信頼モデルを直接標的としています。第二に、単なるデータ窃取用拡張機能として機能するのではなく、GhostChrome-Xはブラウザベースのアクセスとオペレーティングシステムレベルのコマンド実行を統合しており、ブラウザを攻撃者の継続的な作戦活動のための永続的なプラットフォームとして機能させています。
長期的なアクセスを維持するため、GhostChrome-XはPowerShellスクリプト、スケジュールタスク、レジストリのRunキー、ウォッチドッグ機能など、複数の永続化・復旧メカニズムを展開します。これらのコンポーネントにより、悪意のある拡張機能が削除または変更された場合でも、マルウェアは自動的にそれを復元・再インストールできます。
アクティブ化されると、この拡張機能はリモートのコマンド&コントロール(C2)サーバーと通信し、ブラウザのCookie、閲覧履歴、送信されたフォームデータを収集するほか、感染システム上でのリモートコマンド実行にも対応します。さらにこのマルウェアはWebAuthnの活動を監視し、被害者のブラウザセッション内から、攻撃者が制御するWebAuthn対応サイトとのやり取りを可能にします。
GhostChrome-Xで最も重要な点は、情報窃取能力そのものではなく、Chromeの内部整合性メカニズムを悪用して攻撃者制御下の拡張機能を密かに登録・維持できる点です。これは、一般的なブラウザベースマルウェアで見られる水準を超えて、Chromeの拡張機能セキュリティモデルへの深い理解を示すものであり、現代の脅威が単なる認証情報の窃取源としてではなく、運用プラットフォームとしてブラウザをますます活用している実態を浮き彫りにしています。
技術的詳細
初期感染
GhostChrome-Xの初期感染ベクトルは現時点では不明です。しかし Authenticator.exe や chrome_updater.exe といったファイル名が存在することから、このマルウェアは正規の認証ユーティリティやChromeの更新コンポーネントに偽装していた可能性が示唆されます。被害者はフィッシングメール、悪意のあるダウンロード、偽のブラウザ更新、あるいは信頼できるソフトウェア提供元を装ったウェブサイトを通じて、このファイルを実行するよう仕向けられた可能性があります。
Nimベースのローダーとインストーラー
GhostChrome-XはNimプログラミング言語を用いてコンパイルされています。Nimはスタンドアロン実行ファイルを生成できる点、クロスプラットフォーム対応、比較的小さいバイナリサイズなどから、マルウェア開発者の間で人気が高まっている言語です。Nimバイナリは従来のC/C++アプリケーションとは構造やランタイムが異なる場合が多く、解析や検出を難しくする要因となっています。
実行されると、GhostChrome-Xは svc_update.ps1 という名前のPowerShellスクリプトを %TEMP% ディレクトリにドロップし、実行します。悪意のあるChrome拡張機能を登録する前に、このPowerShellスクリプトはChromeの整合性保護された設定ファイルを改変し、Chromeの整合性メタデータ偽造を実行します。具体的には、攻撃者が制御する拡張機能の設定に対して新しい HMAC 値を生成し、それに関連する super_mac 値を算出します。
これらの改変は拡張機能が登録される前に行われるため、Chromeは悪意のある設定を受け入れることになり、整合性検証の失敗を理由に拡張機能を拒否することはありません。整合性メタデータの更新が完了すると、マルウェアは悪意のある拡張機能、ネイティブメッセージングコンポーネント、PowerShellスクリプト、そしてブラウザベースのコマンド&コントロールおよびオペレーティングシステムへのアクセスを確立するために必要な永続化メカニズムの展開へと進みます。
Chrome拡張機能の整合性検証の仕組み
GhostChrome-XがChromeの整合性保護メカニズムをどのように回避するかを理解するには、まずChromeが拡張機能の設定データをどのように保存・検証しているかを把握しておく必要があります。
Chromeは拡張機能の設定データを、ユーザーのChromeプロファイルディレクトリ下にあるPreferencesとSecure Preferencesという2つのプロファイルファイルに保存しています。
- %LOCALAPPDATA%\Google\Chrome\User Data\Default\Preferences
- %LOCALAPPDATA%\Google\Chrome\User Data\Default\Secure Preferences
Preferences ファイルには一般的なブラウザおよび拡張機能の設定が含まれる一方、 Secure Preferences にはChromeが不正な改変を検知するために使用する追加の整合性メタデータが含まれています。ブラウザ起動時、Chromeは両方のファイルを読み込んで拡張機能の状態を再構築し、保護された設定項目の整合性を検証します。
拡張機能がインストールされると、ChromeはPreferencesファイル内のextensions.settings配下に登録エントリを作成します。このエントリには拡張機能ID、インストールパス、権限、インストール日時、状態などの情報が含まれます。簡略化した例を以下に示します。
しかし、拡張機能エントリを単に追加するだけでは十分ではありません。Chromeは protection.macs 構造に保存された整合性レコードによってこれらの設定を保護しています。この例では、HMAC値が拡張機能の登録エントリを保護しています。ブラウザ起動時、Chromeは拡張機能設定のHMACを再計算し、保存されている値と比較します。値が一致しない場合、Chromeはその設定が改変または改ざんされたものとして扱います。
Chromeは開発者モードなど、拡張機能に関連する特定の設定も保護しています。例:
個別のHMACエントリに加え、Chromeはprotection.macs構造全体から算出されるsuper_macと呼ばれるマスター整合性値も保持しています。
そのため、保護された設定を改変するには、単に設定値を変更するだけでは不十分です。対応するHMACも再生成する必要があり、整合性を保つためにsuper_macも再計算しなければなりません。これらの整合性値の更新を怠ると、ブラウザ起動時にChromeの検証プロセスがその改変を検知してしまいます。
GhostChrome-XはChromeの標準的な拡張機能インストールプロセスを使う代わりに、PowerShellスクリプト svc_update.ps1を実行し、ChromeのPreferencesおよびSecure Preferencesファイルを直接改変します。この手法により、マルウェアは通常の拡張機能インストールの仕組みやユーザーの承認に頼ることなく、悪意のある拡張機能を密かに登録し、Chromeが改変された設定を信頼できるものとして受け入れるために必要な整合性メタデータを生成できます。
悪意のあるChrome拡張機能登録のためのHMAC偽造
Chromeが拡張機能の設定データをどのように保存・検証しているかを理解したところで、次にGhostChrome-X がこの仕組みをどのように悪用するかを見ていきます。
スクリプト svc_update.ps1 は、まずインストール済みのChromeディレクトリを特定し、 resources.pak ファイルからChrome固有のマシンキーを抽出することから始まります。続いてデバイス識別子を生成し、図1に示すように、悪意のある拡張機能のパス C:\Users\<user>\AppData\Local\Google\Chrome\User Data\Default\Extensions\Authenticatorに対応する拡張機能IDを算出します。このディレクトリは後に、マルウェアの中核となるブラウザコンポーネントである悪意のあるAuthenticator拡張機能を格納するために使用され、その後Chromeの設定内に登録されます。
これらの値を取得した後、スクリプトはユーザープロファイル内のChromeのPreferencesおよびSecure Preferencesファイルを特定します。これらのファイルは、悪意のある拡張機能を登録し、Chromeが変更を受け入れるために必要な関連整合性メタデータを更新するために、この後改変されます。
Chromeの設定ファイルを特定した後、スクリプトはSecure Preferencesの内容を読み込んで解析します。このファイルが利用できない場合はPreferencesを代わりに使用します。続いて、図2に示すように、Chromeの整合性メタデータから既存の _encrypted_hash エントリを削除します。これにより、悪意のある拡張機能の設定を挿入し、Chromeが改変された設定を受け入れるために必要な新しい整合性値を生成するための準備が整います。
続いてスクリプトは、図3に示すように、悪意のあるAuthenticator拡張機能の完全な登録オブジェクトを構築します。この登録レコードには以下の権限が付与されます。
- activeTab
- background
- clipboardRead
- cookies
- history
- nativeMessaging
- tabs
- declarativeNetRequest
- scripting
さらに、この拡張機能には以下の設定も施されます。
- explicit_host: <all_urls>
- scriptable_host: <all_urls>
<all_urls> 設定により、拡張機能はユーザーが訪れるすべてのウェブサイトにアクセスし、やり取りできるようになります。explicit_hostエントリはすべてのドメインにわたるウェブコンテンツへのアクセスを許可し、scriptable_host はそれらのウェブサイト上でスクリプトを注入・実行することを可能にします。これらの権限が組み合わさることで、拡張機能は被害者の閲覧活動に対する広範な可視性と制御力を手にすることになります。
続いてスクリプトは拡張機能のインストールパスを追加し、状態を「有効」に設定した上で、算出済みの拡張機能IDを用いて登録レコードをChromeの extensions.settings セクションに挿入します。これにより、悪意のあるAuthenticator拡張機能がChromeの設定データベース内に実質的に登録され、ブラウザ起動時に認識・読み込みされるようになります。
悪意のある拡張機能を登録した後、スクリプトは extensions.ui.developer_mode を trueに設定することで、Chromeの開発者モードを有効化します。これにより、ブラウザはディスク上に保存されたファイルから直接Authenticator拡張機能を読み込めるようになります。この拡張機能はChromeの通常のインストールプロセスを経て導入されたものではないため、この処理が必要となります。
続いてスクリプトは、図4に示すように、Chromeの設定内に protection、 macs、 super_mac の各構造がまだ存在しない場合はそれらを作成します。 protection.macs.extensions.settings および protection.macs.extensions.ui配下には追加のコンテナが作成され、これらには後で新たに追加された拡張機能と開発者モード設定に対応する整合性値が格納されます。
悪意のある拡張機能が登録されると、スクリプトは先に抽出したChromeマシンキーとデバイス識別子を用いて、 extensions.ui.developer_mode 設定に対する有効なHMACを生成します。その結果として得られる値は、図5に示すように、Chromeの整合性チェックを満たすために protection.macs.extensions.ui.developer_mode配下に保存されます。
続いてスクリプトは、改変された設定に関連する既存の developer_mode_encrypted_hash および settings_encrypted_hash エントリを削除し、古い整合性値が新しく生成された署名と競合しないようにします。
続いてマルウェアは、 extensions.settings.<extension_id>配下にある悪意のあるAuthenticator拡張機能のエントリに対するHMACを生成します。この整合性値は protection.macs.extensions.settings に挿入され、図6に示すように、新たに追加された拡張機能に対応する整合性レコードが実質的に作成されます。
個々のHMAC値がすべて生成された後、スクリプトは protection.macs 構造全体をシリアライズし、保護された設定データに対するChromeのマスター整合性値となる新しい super_macを算出します。
最後に、悪意のある拡張機能の登録情報、開発者モード設定、新たに生成されたHMAC群、更新後の super_macを含む改変後の設定が、対象の設定ファイル(Secure Preferences)に書き戻されます。これにより整合性偽造プロセスが完了し、改変されたChromeプロファイルは次回のブラウザ起動に備えた状態になります。
Secure Preferencesを更新した後、スクリプトはChromeのPreferencesファイルに対しても同様の改変を行います。悪意のあるAuthenticator拡張機能のエントリを挿入し、 developer_modeを有効化した上で、更新後の設定をディスクに書き戻します。ファイルを保存する前に、スクリプトは図7に示すように exit_type の値を「crashed」から「none」に置き換え、次回起動時にChromeがクラッシュ復旧プロンプトを表示しないようにします。両方の設定ファイルを更新することで、マルウェアは拡張機能の登録情報と開発者モードの設定がChromeの設定データベース全体で一貫性を保つよう担保しています。
追加ペイロードの展開と永続化
長期的なアクセスを維持し、悪意のある拡張機能が確実に機能し続けるようにするため、GhostChrome-Xは C:\Users\<user_name>\AppData\Roaming\Microsoft\Protect\Cache\ディレクトリ内に複数の補助的なPowerShellスクリプトを展開します。具体的には、 http_proxy.ps1、 svc_watchdog.ps1、 svc_integrity.ps1をドロップし、これらが一体となって感染状態を維持するためのインフラを提供します。
続いてGhostChrome-Xは以下のメカニズムを通じて永続化を確立します。
- スケジュールタスク Microsoft\Windows\Application Experience\StartupAppTaskを作成し、5分ごとに svc_watchdog.ps1を実行します。
- スケジュールタスク Microsoft\Windows\Application Experience\ProgramDataUpdaterを作成し、ユーザーがログオンするたびに svc_integrity.ps1を実行します。
- レジストリのRunキー WindowsSecurityUpdateを作成し、ユーザーログオン時に svc_integrity.ps1を実行します。
- レジストリのRunキー SystemHealthMonitorを作成し、ユーザーログオン時に http_proxy.ps1を実行します。
悪意のある拡張機能の展開と設定の復旧
svc_integrity.ps1スクリプトは、このマルウェアの主要なインストール・復旧メカニズムとして機能します。このスクリプトはユーザーログオン時に ProgramDataUpdaterスケジュールタスクを通じて実行されるほか、 svc_watchdog.ps1からも呼び出されます。その結果、GhostChrome-Xはブラウザベースのコンポーネントが部分的に削除された場合でも、自動的にそれを復元できます。
実行されると、このスクリプトはまず稼働中のChromeプロセスをすべて終了させ、以下の場所に悪意のあるAuthenticator拡張機能のディレクトリを作成します。
- C:\Users\aptma\AppData\Local\Google\Chrome\UserData\Default\Extensions\Authenticator\
続いて、図8に示すように、スクリプト自体に埋め込まれたBase64エンコード済みデータから、 background.js、 content.js、 manifest.jsonを含む拡張機能のコンポーネントを書き込みます。これらのファイルが、拡張機能のコマンド&コントロール通信、データ収集機能、ブラウザとの連携機能を実装しています。
拡張機能ファイルを展開した後、スクリプトは前述のChrome設定・整合性操作プロセスを繰り返し実行します。これにより、設定が改変されたり部分的に削除されたりした場合でも、悪意のある拡張機能が登録され、信頼された状態を保ち、ブラウザに読み込まれ続けるようにします。
最後にスクリプトは、ローカルのHTTPコマンド実行サービスが 127.0.0.1:18923で稼働しているかを検証します。サービスが利用できない場合は自動的に http_proxy.ps1を起動し、拡張機能がリモートのコマンド&コントロールインフラから受け取ったオペレーティングシステムコマンドを実行する能力を維持できるようにします。
ローカルコマンド実行サービス
http_proxy.ps1は 127.0.0.1: 18923上でローカルHTTPサービスを起動します。このサービスは悪意のあるブラウザ拡張機能からのリクエストを常時待ち受け、JSON形式で受け取ったコマンドを処理します。
このスクリプトは shell_commandと ls_commandという2つのコマンドに対応しています。 shell_command命令は cmd.exeを通じて任意のコマンドを実行し、 ls_commandは図9に示すように、指定されたパスのディレクトリ一覧を取得してリクエスト元に結果を返します。
要求された処理を実行した後、スクリプトはその出力をJSONレスポンスにまとめて拡張機能に返送します。このサービスはバックグラウンドで稼働し続け、拡張機能自身が直接プロセスを起動することなくオペレーティングシステムとやり取りできるようにします。
リモートのC2サーバーから受信したコマンドは、拡張機能によってこのローカルサービスに転送され、被害者のシステム上で実行された後、その結果が拡張機能に返され攻撃者へ送信されます。
Chromeのネイティブメッセージング機能を悪用したコマンド実行
GhostChrome-X は主に、 http_proxy.ps1が実装するローカルHTTPサービスを通じてオペレーティングシステムのコマンドを実行します。しかし、副次的な実行メカニズムとして、ローカルHTTPサービスが利用できなくなった場合に備え、コマンド実行能力を維持するためにChromeのネイティブメッセージング機能も悪用します。
悪意のあるAuthenticator拡張機能とローカルのオペレーティングシステムプロセスとの通信を可能にするため、GhostChrome-Xは以下のレジストリエントリを作成することで、Chromeネイティブメッセージングホストを登録します。
- “HKCU\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.google.authenticator” /ve /d “C:\Users\<user_name>\AppData\Local\Google\Chrome\User Data\Default\Extensions\Authenticator\NativeHost\com.google.authenticator.json” /f
このコマンドは現在のユーザーのChromeプロファイル下にネイティブメッセージングホストの登録を作成し、ホスト名 com.google.authenticatorを、以下の場所にある com.google.authenticator.jsonという名前のマニフェストファイルに関連付けます。
- C:\Users\<user_name>\AppData\Local\Google\Chrome\User Data\Default\Extensions\Authenticator\NativeHost\
悪意のある拡張機能が chrome.runtime.sendNativeMessage() APIを呼び出すと、Chromeは登録済みのマニフェストファイルを特定し、その設定を読み込んで、設定済みのネイティブメッセージングホストを起動します。
この攻撃キャンペーンでは、マニフェストファイルは同じ NativeHostディレクトリに格納されている host.cmdを指しており、これが拡張機能から受け取ったコマンドを処理するネイティブメッセージングホストとして機能します。 http_proxy.ps1が実装するローカルHTTPサービスとの通信が失敗した場合、background.jsは自動的にネイティブメッセージングにフォールバックし、 com.google.authenticatorホストを通じてコマンドを転送します。その結果、GhostChrome-Xは副次的なブラウザ・システム間通信チャネルを確立し、リモートC2サーバーから受け取ったコマンドを被害者のシステム上で実行できるようにします。
拡張機能マニフェストの設定
拡張機能の manifest.jsonファイルは、このマルウェアの動作に必要なコンポーネントと権限を定義しています。この設定では background.jsを拡張機能のサービスワーカーとして登録し、図10に示すように、 <all_urls>のマッチパターンを通じて被害者が訪れるすべてのウェブサイトに content.jsを注入します。
このマニフェストは、cookies、history、tabs、scripting、clipboardRead、nativeMessaging、declarativeNetRequestなど、複数の高リスクな権限を付与します。これらの権限により、拡張機能はブラウザのCookieへのアクセス、閲覧履歴の収集、ブラウザタブとの連携、ウェブページへのスクリプト注入、Chromeネイティブメッセージングを通じたローカルプロセスとの通信、ネットワーク関連のブラウザ動作の変更が可能になります。
バックグラウンドサービスワーカーとC2通信
background.jsファイルは、悪意のあるAuthenticator拡張機能の主要なコマンド&コントロールコンポーネントとして機能します。読み込まれると、ハードコードされた認証トークンを用いて wss://authenticators.duckdns.org/wsへの永続的なWebSocket接続を確立し、攻撃者からのコマンドを継続的に待ち受けます。
この拡張機能は、図11に示すように、感染システムからブラウザのCookieと閲覧履歴を取得できる dump_cookiesや dump_historyなどのブラウザデータ収集操作を含む、複数のコマンドに対応しています。
オペレーティングシステムとの連携については、この拡張機能は shell_commandと ls_commandに対応しています。これらのコマンドをC2サーバーから受信すると、 background.jsはそれらを http_proxy.ps1が実装する 127.0.0.1: 18923で稼働するローカルHTTPサービスに転送します。PowerShellスクリプトは要求されたコマンドを実行し、その結果を拡張機能に返却します。拡張機能はその出力をWebSocket接続経由で攻撃者に送り返します。
フォームデータとWebAuthnの傍受
content.jsファイルは被害者が訪れるウェブサイトに注入され、ウェブページからのデータ収集を担います。このスクリプトはHTMLフォームを監視し、図12に示すように、フィールド名、値、現在のページURLを含む送信済みフォームデータを取得します。この情報は拡張機能のバックグラウンドサービスワーカーに送信され、収集されたデータは攻撃者のC2サーバーに転送されます。
フォーム送信を監視することで、GhostChrome-Xはユーザー名、パスワード、メールアドレス、連絡先情報、支払い情報など、HTMLフォームを通じてウェブアプリケーションに入力される機密情報を収集できます。
フォーム監視に加え、このスクリプトは navigator.credentials.get()関数をフックすることで、WebAuthn認証リクエストを傍受します。ウェブサイトがWebAuthn認証操作を実行しようとするたびに、拡張機能はそのイベントを記録し、バックグラウンドサービスワーカーに通知します。
また、このスクリプトは拡張機能を通じて受信した webauthn_requestコマンドの処理も行います。トリガーされると、図13に示すように、非表示のiframeを作成し、攻撃者が制御するURLを読み込んで、WebAuthnリクエストデータをそのページに渡します。このiframeにはWebAuthn APIの使用権限が付与されており、被害者のブラウザセッション内で攻撃者が制御するコンテンツを実行できるようになります。
この機能の正確な目的は入手可能なコードからは特定できませんが、パスキー、セキュリティキー、その他のWebAuthnベースの認証メカニズムを使用するウェブサイトに対して、攻撃者が制御下のやり取りを行うことを可能にします。これにより攻撃者は、被害者の認証済みブラウザコンテキスト内から、WebAuthn関連の活動を監視したり開始したりできる可能性があります。
結論
GhostChrome-Xは、現代の脅威がブラウザを永続化、監視、システムアクセスのためのプラットフォームとしてますます活用している実態を浮き彫りにしています。データ収集機能自体は比較的単純なものですが、このマルウェアがブラウザ拡張機能、ネイティブメッセージング、コマンド実行、復旧メカニズムを統合していることで、攻撃者は侵害したシステムに強靭な足場を築くことができます。ブラウザが認証やオンラインサービスへのアクセスにおいて中心的な役割を担い続ける限り、信頼されたブラウザ機能の悪用は今後も脅威アクターにとって魅力的な手法であり続けるとみられます。
翻訳元: https://zerolabs.rubrik.com/blog/inside-ghostchrome-x-chrome-extension-integrity-bypass