リポジトリと組織のシークレットをすべてJSON形式でダンプし、よく知られたパスにある認証情報ファイルやシェル履歴、AIサービスのAPIキーまで盗み出します。
乗っ取られたGitHubアカウントを使い、シークレット窃取マルウェアを数千のリポジトリに拡散させる攻撃キャンペーンが見つかりました。ペイロードは少なくとも1,806のリポジトリで実行され、CI/CDのシークレットやクラウドの認証情報が外部に送信されました。
このキャンペーンを検知して詳細を公表したAikido Securityによると、攻撃者は4,837件の侵害済みアカウントを使い、11月10日から61,764のリポジトリに探査用のプルリクエストを送りました。「docs: dependency audit notes」というタイトルのこれらのプルリクエストは、約92%がいまも未処理のままです。多くのプロジェクト管理者が気づいていないとみられます。
ただし、探査用のプルリクエストそのものに害はありません。乗っ取ったアカウントが各リポジトリへの書き込み権限を持っているかを確かめるのが目的でした。権限を確認した後、攻撃者は悪意あるペイロードを含むコミットを送り込みます。ペイロードは約1,500行のシェルスクリプトで、GitHub Actionsのシークレット、クラウドの認証情報、AIサービスや開発者向けツールのAPIキーを収集します。
ペイロードの配布には、少なくとも3つの手口が使われました。1つ目は既存のGitHub Actionsワークフローの改ざんです。2つ目はpackage.jsonファイルへのpostinstallフックの追加で、npm installを実行するたびにペイロードが動きます。3つ目は、不正なActionsワークフローを載せた使い捨てブランチを作成し、それを実行させる方法です。
Aikidoの研究者らはレポートで次のように述べています。「少なくとも1,806のリポジトリでペイロードが実行された形跡を確認しましたが、実際の被害はこれより大きい可能性があります。影響を受けたリポジトリでは実行ログが削除されていました。攻撃者はすでに認証情報を回収し、痕跡も消したとみられます」
GitHubの防御をすり抜けたnpmフック
GitHubの防御策は、検知できたペイロードに対しては想定どおりに機能しました。同プラットフォームは、悪意あるワークフローの実行前に明示的な承認を求める仕組みを導入し、最近のワークフロー注入キャンペーンの被害を抑えてきました。GitGuardianの調査でも、ワークフローファイル上でまだ確認できた11月のペイロード実行7件は、すべてaction_required状態のままで、開始されていませんでした。
ニュースレター
AIニュース、分析、インサイト
AIのリスクと恩恵に向き合うIT部門のリーダーに向けた、当社各サイトの編集者による特集シリーズです。
最新のAI情報を毎週火曜日に配信
GitGuardianのセキュリティ研究者Gaetan Ferry氏は、分析で次のように述べています。「GitHubはワークフロー形式の攻撃を止めましたが、npmフックは保留をすり抜けて実行されました」
npmフックはワークフローファイルを一切変更しないためです。攻撃者はリポジトリのルートに隠しスクリプトを置き、package.jsonに1行を加えました。この1行はnpm installのたびに実行されます。リポジトリにもともとあった未改変のワークフローが、通常のビルド処理としてnpm installを実行していました。
攻撃者は木曜日までに、窃取データの送信方法も変えています。最新のペイロードは、盗んだデータをTelegramのチャットにのみ送ります。HTTPコールバックの宛先は、すでに無効なアドレスです。これまでに公表されたIPアドレスをブロックしても、最新版は止められません。
マルウェアが盗む情報
スクリプトは実行されると、ワークフローのsecretsオブジェクトをJSON形式でダンプし、リポジトリと組織のシークレットをすべて取得します。さらにランナープロセスのメモリをスキャンします。メモリ上には、ワークフローが参照していないものも含め、シークレットが復号された状態で残っています。加えて、よく知られたパスにある認証情報ファイルやシェル履歴、OpenAI、Anthropic、Copilot、CursorといったAIサービスや開発者向けツールのAPIキーも収集します。
スクリプトの動作はこれにとどまりません。OIDCトークンをAWS、GCP、Azureのセッションと交換し、有効期限の長い新しいAWSアクセスキーを発行します。GCPのサービスアカウントになりすまし、キャッシュされたAzureのリフレッシュトークンを再利用して、Microsoft GraphやKey Vaultにも到達します。
収集した情報はgzip形式のアーカイブにまとめて攻撃者に送信され、その後に痕跡が消去されます。ほとんどのリポジトリでは、攻撃者は1分以内に悪意あるコミットを取り消し、ワークフローの実行とログも削除しました。
認証情報をローテーションしても残るバックドア
スクリプトは、認証情報がリセットされても攻撃者がアクセスを維持できるように細工もします。AWSでは、引き受けたロールの信頼ポリシーを書き換えて、あらゆるAWSアカウントからの利用を許可します。これでロールは誰にでも開放された状態になります。さらにiam:CreateAccessKey APIを呼び出し、IAMユーザー用に有効期限の長いキーを作成します。
Azureでは、wfx-ci-*という名前のフェデレーションID資格情報をアプリケーションに注入し、侵害されたリポジトリを参照するように設定します。これにより、すべてのトークンをローテーションした後でも、そのリポジトリのどのワークフローも、保存されたシークレットなしでAzureに認証できます。
管理するリポジトリに探査用のプルリクエストや、このキャンペーンのコミット文字列が見つかった場合は、そのリポジトリのワークフローが到達できたシークレットはすべて盗まれたとみなす必要があります。リポジトリと組織のシークレット、パッケージレジストリのトークン、クラウドのキーをローテーションしてください。メモリスキャンが行われるため、盗まれた情報の範囲は、ワークフローが参照していたものより広くなる点にも注意が必要です。
そのうえで、永続化の痕跡を調べてください。確認すべきは、あらゆるアカウントを受け入れるAWSロールの信頼ポリシー、11月10日以降に作成されたIAMキー、wfx-ci-*という名前のAzureフェデレーション資格情報です。
ArmorCodeのシニアプリンシパルソリューションエンジニアであるRamy Rahman氏は、CSOの取材に次のように述べています。「すべてのログを有効にしてください。特にクラウド管理者の操作に関する監査ログが重要です。可能な範囲で監査ログを調べ、特にAWSとAzureでは永続化される恐れがあるため、悪意あるペイロードが実行されていないことを確認してください」
wfx-lootのペイロードは、公開されたパッケージにも含まれていました。Packagistのパッケージneuronai-studio 3.14.3と、Goモジュールのdocker-env、gocurlです。Goモジュールでは、ペイロードはGoのツールが実行しないワークフローファイルにしか存在しません。そのため、利用者は影響を受けていない可能性があります。一方、Packagist版をインストールしたマシンは、侵害されたものとして扱うべきです。
GitGuardianによると、このキャンペーンの開始に使われたGitHubアカウントの約5分の1は、10月に発生したGhostAction攻撃の際にすでに侵害されていました。一方、StepSecurityの研究者らは、探査用プルリクエストのうち173件が、Fly.ioのGitHub Appに発行されたトークンから送られたものであることを突き止めました。
Fly.ioは、これらのトークンが漏えいしたことを認めました。デプロイ処理の過程で、ビルドディレクトリ内の.git/configファイルにトークンが残っていたためです。一部のアプリは、このディレクトリを一般に公開していました。ただし、Fly.io自体が侵害されたわけではないとしています。GitHubはFly.ioアプリのトークンを一括で失効させましたが、処理は途中で止まりました。盗まれたトークンの一部は、まだ有効な可能性があります。