プレインストールから永続化まで:Red Hat npmミアスマ資格情報窃盗キャンペーンの内側
Detection stack
- AIDR
- Alert
- ETL
- Query
概要
Microsoft Defenderが、下記の名前空間で公開された32のnpmパッケージにサプライチェーンの妥協があることを特定しました @redhat-cloud-services 攻撃者は、重度に難読化されたJavaScriptローダーを展開する事前インストールフックを埋め込み、さらにBunランタイムと二段階の認証情報窃取プログラムを取得します。このマルウェアはGitHub、npm、主要なクラウドプロバイダー、HashiCorp Vault、Kubernetesからトークンを収集し、毒されたパッケージを再公開して拡散を続けます。また、このキャンペーンには、偽装トークンが検出された場合に被害者のホームディレクトリを消去する破壊的なセーフガードも含まれています。
調査
調査により、初期侵害は RedHatInsights/javascript-clientsのCI/CDパイプラインが危険にさらされ、攻撃者が正規のGitHub Actions OIDCワークフローを悪用して、有効な出所署名付きのトロイの木馬化されたパッケージを公開したことにさかのぼりました。ドロッパーの分析で、ROTベースのエンコーディング、AES-128-GCM暗号化およびカスタム暗号を含む多層の難読化が露呈され、その後Bunが実行されて二段階のペイロードが起動されました。さらに、攻撃者はGitHub Actionsランナーのメモリをスクレイピングして、アクティブなプロセスから直接シークレットを抽出しました。
軽減策
Microsoftは影響を受けた @redhat-cloud-services パッケージの依存関係ツリーを確認し、信頼済みバージョンを固定し、可能であれば --ignore-scripts フラグを使ってnpmスクリプトの実行を無効にすることを推奨します。すべての妥協されたnpmトークンを取り消し再発行し、GitHubアカウントも不正なリポジトリの作成や疑わしい活動について確認するべきです。これ以降は、無許可の公開を防ぐため、 @redhat-cloud-services 名前空間内で追加の安全策が実施されています。
対応
防御者は、疑わしいnpmの事前インストール実行や、一時ディレクトリからの予期しないBunランタイムの起動を検出するべきです。また、不明な公開GitHubリポジトリの生成と異常なトークン使用パターンを監視する必要があります。ネットワーク防御は、既知のBunダウンロードURLや api.anthropic.com ドメインへの接続をブロックまたは警告しなければなりません。潜在的に露呈した認証情報は直ちに回転し、CI/CDランナーのメモリ内に漏洩したシークレットの兆候を調査する必要があります。
"graph TB %% クラス定義 classDef action fill:#99ccff classDef tool fill:#cccccc classDef malware fill:#ffcc99 classDef process fill:#ff9966 %% ノード node_sc_001["<b>アクション</b> – <b>T1195.001 サプライチェーン妥協</b>: ソフトウェア依存関係と開発ツールを妥協させる<br/>攻撃者はRedHatInsights/javascript-clients CI/CDパイプラインを乗っ取り、GitHub Actions OIDCを使用してトロイの木馬化された@redhat-cloud-services npmパッケージを公開しました。"] class node_sc_001 action tool_github_oidc["<b>ツール</b> – <b>名前</b>: GitHub Actions OIDC<br/><b>説明</b>: CIワークフローに短期間有効なトークンを提供するOpenID Connectインテグレーション。"] class tool_github_oidc tool malicious_preinstall["<b>マルウェア</b> – <b>T1127.003 信頼された開発者ユーティリティプロキシ実行</b>: package.jsonの中の悪意ある事前インストールフックが<code>npm install</code>中に自動的に実行され、<code>node index.js</code>を生成。"] class malicious_preinstall malware installer_trigger["<b>アクション</b> – <b>T1546.016 イベントトリガー実行</b>: インストーラーパッケージトリガーが事前インストールスクリプト呼び出し時にドロッパーを実行。"] class installer_trigger action obfuscated_payload["<b>マルウェア</b> – <b>T1027.009 難読化されたファイルまたは情報</b>: マルチレイヤーのROT、AES-128-GCM、文字列配列およびカスタムPBKDF2暗号を用いてコードを隠している埋め込みペイロード (4.29 MB index.js)。"] class obfuscated_payload malware dynamic_resolution["<b>マルウェア</b> – <b>T1027.007 難読化されたファイルまたは情報</b>: 動的API解決 – ランタイム難読化解除でBunランタイムとC2エンドポイントのURLを解決。"] class dynamic_resolution malware ingress_transfer["<b>アクション</b> – <b>T1105 インバウンドツール転送</b>: ドロッパーが公式リリースURLからBun JavaScriptランタイムをダウンロードし、二段階のペイロードを実行。"] class ingress_transfer action tool_bun_runtime["<b>ツール</b> – <b>名前</b>: Bun JavaScript Runtime<br/><b>説明</b>: 第二段階の実行環境として使われる高性能JavaScriptエンジン。"] class tool_bun_runtime tool metadata_query["<b>アクション</b> – <b>T1552.005 セキュアでないクレデンシャル</b>: クラウドインスタンスメタデータAPI<br/>AWS/ECS、Azure IMDS、GCPメタデータサービスを問い合わせてクラウドアクセス トークンを取得。"] class metadata_query action file_credential["<b>アクション</b> – <b>T1552.001 セキュアでないクレデンシャル</b>: ファイル内のクレデンシャル<br/>SSHキー、CLI設定、暗号通貨ウォレットファイル、その他の秘密資料をローカル ファイルからスクレイピング。"] class file_credential action token_harvest["<b>アクション</b> – <b>T1528 アプリケーショントークンの窃取</b>: GitHub Actionsランナートークン、npm OIDCトークン、他のプロバイダートークンを収集。"] class token_harvest action browser_discovery["<b>アクション</b> – <b>T1217 ブラウザインフォメーションディスカバリー</b>: 開発者ワークステーションからブラウザストアと暗号通貨ウォレットファイルを収集。"] class browser_discovery action elevation_control["<b>アクション</b> – <b>T1548 エレベーションコントロールメカニズムの悪用</b>: bindマウントされた≪code>/etc/sudoers.d≪/code> を介してパスワードなしのsudoルールをインストールし、root権限を取得。"] class elevation_control action exfiltration_git["<b>アクション</b> – <b>T1048 代替プロトコルによる外部転送</b>: 被害者のアカウント下でGitHubリポジトリを作成し、JSONファイルをコミットして、盗まれた認証情報を外部転送し、代替HTTPSエンドポイントも使用。"] class exfiltration_git action destructive_cleanup["<b>アクション</b> – <b>T1070.010 インジケーターの削除</b>: マルウェアを移動させ、フィラースイッチングが使われた場合、<code>rm -rf ~/</code>を実行してユーザーのホームディレクトリを消去。"] class destructive_cleanup action node_sc_002["<b>アクション</b> – <b>T1195.002 サプライチェーン妥協</b>: ソフトウェアサプライチェーンの妥協 – 偽造SLSA出所で毒されたパッケージを再出版し、下流プロジェクトへのワーム状の伝播を可能に。"] class node_sc_002 action %% コネクション node_sc_001 –>|使用| tool_github_oidc tool_github_oidc –>|実行| malicious_preinstall malicious_preinstall –>|トリガー| installer_trigger installer_trigger –>|実行| obfuscated_payload obfuscated_payload –>|実行| dynamic_resolution dynamic_resolution –>|ダウンロード| ingress_transfer ingress_transfer –>|インストール| tool_bun_runtime tool_bun_runtime –>|クエリー| metadata_query metadata_query –>|スクレイピング| file_credential file_credential –>|収集| token_harvest token_harvest –>|収集| browser_discovery browser_discovery –>|エネーブル| elevation_control elevation_control –>|外部転送 via| exfiltration_git exfiltration_git –>|トリガーする可能性あり| destructive_cleanup destructive_cleanup –>|支援| node_sc_002 node_sc_002 –>|伝播 to| node_sc_001 "
攻撃の流れ
検出
標準ツールを介したリモートファイルアップロード/ダウンロード(コマンドライン経由)
表示
検出するためのIOCs(HashSha256):Red Hat npm Miasma 認証情報盗みのキャンペーンにおける事前インストールからの永続性
表示
Bunランタイム実行での疑わしいNode.jsプロセス挙動 [Windowsプロセス生成]
表示
Bunランタイム実行およびパスワードなしのSudoルール検出 [Linuxプロセス生成]
表示
GCPサービスアカウントトークン収集 by Miasma キャンペーン [Google Cloud Platform]
表示
無許可のAzure IMDS OAuth2トークンアクセスの検出 [Azureアクティビティログ]
表示
IMDS OAuth2トークン取得およびSecrets Managerアクセスを介した認証情報アクセス [AWS Cloudtrail]
表示
シミュレーション実行
前提条件:テレメトリーとベースラインの事前フライトチェックが合格している必要がある。
根拠:このセクションは、検出ルールをトリガーするように設計された敵技術(TTP)の正確な実行を詳細に説明します。コマンドとナラティブは、特定されたTTPを直接反映し、検出ロジックによって期待される正確なテレメトリーを生成することを目的としています。
-
攻撃の説明とコマンド:
既にGCE VMを妥協している敵者は、 土地を活用する アプローチを使用して、VMのデフォルトサービスアカウントトークンを収集します。ステップは次の通りです:- メタデータサーバを探索 して、それが到達可能であることを確認する。
- トークンリクエストを発行 to
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token必要なMetadata-Flavor: Googleヘッダで - 返されたJSONを保存 (
access_token,expires_in,token_typeを含む). - トークンを使用して、(例:すべてのバケットを一覧表示する)特権GCP APIを呼び出し、実行可能なクレデンシャルを実証する。 to call a privileged GCP API (e.g., list all buckets) to demonstrate actionable credentials.
この正確な手順によって、
GCPサービスアカウントトークンアクセスという監査イベントを生成し、それがSigmaルールの選択. -
回帰テストスクリプト:
#!/usr/bin/env bash set -euo pipefail # 1. メタデータサーバへの到達可能性の確認 echo "[*] メタデータサーバを探索中..." curl -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/id" >/dev/null # 2. デフォルトサービスアカウントトークンの収集 echo "[*] サービスアカウントトークンを要求中..." TOKEN_RESPONSE=$(curl -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token") echo "[+] トークンの応答を受け取りました:" echo "${TOKEN_RESPONSE}" | jq . # 3. アクセストークンの抽出 ACCESS_TOKEN=$(echo "${TOKEN_RESPONSE}" | jq -r '.access_token') # 4. トークンを使用してGCSバケットを一覧化(トークンの有用性を示すため) echo "[*] トークンを使用してGCSバケットを一覧表示中..." curl -s -H "Authorization: Bearer ${ACCESS_TOKEN}" "https://storage.googleapis.com/storage/v1/b" | jq . echo "[+] シミュレーション完了。この上記の行動は、GCPサービスアカウントトークンアクセス監査イベントを生成するはずです。" -
クリーンアップコマンド:
# 永続的な変更は行われていないため、一時変数を削除するのみ。 unset TOKEN_RESPONSE ACCESS_TOKEN echo "[*] クリーンアップ完了。"