エグゼクティブサマリー
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スクリプト、そしてブラウザ経由のコマンド&コントロールおよびOSアクセスを確立するために必要な永続化メカニズムの展開へと進みます。
Chrome拡張機能の整合性検証の仕組み
GhostChrome-XがChromeの整合性保護メカニズムをどのように回避するのかを理解するには、まずChromeが拡張機能の設定データをどのように保存・検証しているかを把握しておく必要があります。
Chromeは拡張機能の設定データを、ユーザーのChromeプロファイルディレクトリ配下にある2つのプロファイルファイル、PreferencesとSecure Preferencesに保存します。
- %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の標準的な拡張機能インストールプロセスを使う代わりに、ChromeのPreferencesファイルおよびSecure Preferencesファイルを直接改変するPowerShellスクリプト、svc_update.ps1を実行します。この手法により、通常の拡張機能インストールフローやユーザーの承認を経ることなく、悪意ある拡張機能をひそかに登録し、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にその変更を受け入れさせるために必要な関連の整合性メタデータを更新するべく、これらのファイルを改変します。
図1 – 拡張機能IDの生成とChromeプロファイルの特定“>
Chromeの設定ファイルを特定した後、スクリプトはSecure Preferencesの内容を読み込み、解析します。このファイルが利用できない場合は、代わりにPreferencesを使用します。続いて、図2に示すように、Chromeの整合性メタデータから既存の_encrypted_hashエントリを削除します。これにより、悪意ある拡張機能の設定を挿入し、Chromeが変更後の設定を受け入れるために必要な新しい整合性値を生成するための準備が整います。
図2 – preference/Secure Preferencesファイルからの暗号化ハッシュの削除“>
続いて、図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の設定データベースに登録され、ブラウザ起動時に認識・読み込みが可能な状態になります。
図3 – 拡張機能の設定“>
悪意ある拡張機能を登録した後、スクリプトはextensions.ui.developer_modeをtrueに設定することで、Chromeの開発者モードを有効化します。これにより、ブラウザはディスク上に保存されたファイルから直接Authenticator拡張機能を読み込めるようになります。この拡張機能はChromeの通常のインストールプロセスを経て導入されたものではないため、この設定変更が必要になります。
続いてスクリプトは、図4に示すように、Chromeの設定内にまだ存在しない場合はprotection、macs、super_mac の各構造体を作成します。protection.macs.extensions.settingsとprotection.macs.extensions.uiの配下に追加のコンテナが作成され、これらには後ほど、新たに追加された拡張機能および開発者 モード設定に対応する整合性値が格納されます。
図4 – Chrome整合性メタデータ構造体の作成“>
悪意ある拡張機能の登録後、スクリプトは先ほど抽出したChromeのマシンキーとデバイス識別子を用いて、extensions.ui.developer_mode設定に対する有効なHMACを生成します。生成された値は、図5に示すように、Chromeの整合性チェックを満たすためにprotection.macs.extensions.ui.developer_mode配下に格納されます。
続いてスクリプトは、改変後の設定に関連付けられた既存のdeveloper_mode_encrypted_hashとsettings_encrypted_hashのエントリを削除し、古い整合性値が新たに生成された署名と競合しないようにします。
図5 – 開発者モードHMACの生成“>
その後マルウェアは、extensions.settings.<extension_id>配下にある悪意あるAuthenticator拡張機能のエントリに対するHMACを生成します。この整合性値はprotection.macs.extensions.settingsに挿入され、図6に示すように、新たに追加された拡張機能に対応する整合性レコードが事実上作成されます。
すべての個別HMAC値の生成が完了すると、スクリプトはprotection.macs構造体全体をシリアライズし、保護対象の設定データに対するChromeのマスター整合性値として機能する新たなsuper_macを計算します。
最後に、悪意ある拡張機能の登録情報、開発者モード設定、新たに生成されたHMAC群、更新後のsuper_macを含む改変後の設定が、対象の設定ファイル(Secure Preferences)に書き戻されます。これにより整合性偽造プロセスが完了し、次回のブラウザ起動に向けて改変済みのChromeプロファイルが準備されます。
図6 – 拡張機能のHMACとsuper_macの生成“>
Secure Preferencesの更新後、スクリプトはChromeのPreferencesファイルに対しても同様の改変を行います。悪意あるAuthenticator拡張機能のエントリを挿入し、developer_modeを有効化した上で、更新後の設定をディスクに書き戻します。ファイルを保存する前に、スクリプトは図7に示すように、exit_typeの値を「crashed」から「none」に置き換え、次回起動時にChromeがクラッシュ復旧のプロンプトを表示しないようにします。両方の設定ファイルを更新することで、このマルウェアは拡張機能の登録内容と開発者モードの設定がChromeの設定データベース全体で一貫した状態に保たれるようにしています。
図7 – Chrome Preferencesファイルの改変“>
追加ペイロードの展開と永続化
長期的なアクセスを維持し、悪意ある拡張機能が引き続き機能し続けるようにするため、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といった拡張機能のコンポーネントを書き出します。これらのファイルは、拡張機能のコマンド&コントロール通信、データ収集機能、ブラウザとのやり取り機能を実装しています。
図8 – svc_integrity.ps1の内容”>
拡張機能ファイルを展開した後、スクリプトは先述した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サーバーから受信したコマンドは、拡張機能によってこのローカルサービスに転送され、被害者のシステム上で実行された後、その結果が拡張機能に返され、攻撃者への送信に用いられます。
図9 – コマンド実行“>
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のネイティブメッセージングを通じたローカルプロセスとの通信、ネットワーク関連のブラウザ動作の改変が可能になります。
図10 – Manifest.json “>
バックグラウンドサービスワーカーと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接続を通じてその出力を攻撃者に送り返します。
図11 – コマンド実行“>
フォームデータとWebAuthnの傍受
content.jsファイルは被害者が閲覧するウェブサイトに注入され、ウェブページからデータを収集する役割を担います。このスクリプトはHTMLフォームを監視し、図12に示すように、フィールド名、値、現在のページURLを含む、送信されたフォームデータを取得します。この情報は拡張機能のバックグラウンドサービスワーカーに送信され、収集されたデータは攻撃者のC2サーバーへと転送されます。
フォームの送信内容を監視することで、GhostChrome-Xはユーザー名、パスワード、メールアドレス、連絡先情報、支払い情報など、HTMLフォームを通じてウェブアプリケーションに入力された機微な情報を収集できます。
フォームの監視に加え、このスクリプトはnavigator.credentials.get()関数をフックすることで、WebAuthn認証リクエストを傍受します。ウェブサイトがWebAuthn認証操作を実行しようとするたびに、拡張機能はそのイベントを記録し、バックグラウンドサービスワーカーに通知します。
図12 – Content.json“>
このスクリプトはまた、拡張機能を通じて受信したwebauthn_requestコマンドも処理します。トリガーされると、図13に示すように、非表示のiframeを作成し、攻撃者が制御するURLを読み込むと同時に、WebAuthnのリクエストデータをそのページに渡します。このiframeにはWebAuthn APIの使用権限が付与されており、被害者のブラウザセッション内で攻撃者が制御するコンテンツを実行できるようになっています。
この機能の正確な目的は、入手可能なコードからは特定できませんが、パスキー、セキュリティキー、その他WebAuthnベースの認証メカニズムを使用するウェブサイトに対する、攻撃者主導のやり取りを可能にします。これにより攻撃者は、被害者の認証済みブラウザコンテキスト内から、WebAuthn関連の活動を監視したり開始したりできる可能性があります。
図13 – 非表示のIframeを通じたWebAuthnリクエストの処理“>
結論
GhostChrome-Xは、現代の脅威がブラウザを永続化・監視・システムアクセスのための基盤としてますます活用するようになっている実態を浮き彫りにしています。データ収集能力自体は比較的単純なものですが、このマルウェアがブラウザ拡張機能、ネイティブメッセージング、コマンド実行、復旧メカニズムを統合していることで、攻撃者は侵害したシステムに対する強固な足場を得ることになります。ブラウザが認証やオンラインサービスへのアクセスにおいて中心的な役割を果たし続ける中、信頼されたブラウザ機能の悪用は、今後も脅威アクターにとって魅力的な手法であり続けると考えられます。
翻訳元: https://zerolabs.rubrik.com/blog/inside-ghostchrome-x-chrome-extension-integrity-bypass