Gheistキャンペーン:盗まれたGitHubトークンを使用した秘密情報ダンプワークフローの仕掛け
Gheist campaign plants secret-dumping workflows using stolen GitHub tokens (wiz.io)
要約
Wiz Researchは、盗まれたGitHubトークンを悪用してリポジトリ内の秘密情報を窃取しようとする「Gheist」と呼ばれる新たなキャンペーンを追跡しています。この攻撃は、リポジトリに「sync-check」という名前のワークフローを仕掛け、秘密情報をログに出力した後、そのログを削除するという手口を使います。GitHubの対策により公開リポジトリでの攻撃は阻止されていますが、プライベートリポジトリやエンタープライズ環境では成功例が確認されています。
全文翻訳
Gheist:盗まれたGitHubトークンの大規模悪用試行が頓挫
2026年9月15日以降、Wiz ResearchはGheist、すなわち侵害されたGitHubトークンを大規模に悪用する新しいキャンペーンを追跡しています。この攻撃は、各トークンがアクセスできるすべてのリポジトリに sync-check という名前のワークフローをコミットします。このワークフローは、リポジトリの秘密情報を自身のワークフローログに出力しようとします。その後、ツールはGitHub APIを通じてログをダウンロードし、数秒後に実行を削除します。ツールのAPIリクエストは gheist というユーザーエージェントを運び、これがキャンペーンの名前の由来となっています。
個人プロジェクトからエンタープライズ組織のプライベートリポジトリまで、850以上の侵害されたアカウントから13,500以上の仕掛けられたブランチを回収しました。
最近のGitHubの制御により、公開リポジトリでの悪用はブロックされていますが、プライベートリポジトリやGitHubエンタープライズ環境での成功した悪用とそれに続く活動を観測しています。
10月24日現在:
- 攻撃は継続中であり、進化しています。
- 関係するアカウントの約3分の2はGitHub上で利用できなくなっています。これは、この活動をGitHubに報告したため、対応活動を示している可能性が高いです。
攻撃の仕組み
各リポジトリに対し、ツールは ci-sync- という名前のブランチに6文字のランダムな文字列を付加して作成し、コミットメッセージ ci: sync config で .github/workflows/sync-check.yml をコミットします。コミットは署名されておらず、トークン所有者として作成されます。プッシュイベントがワークフローをトリガーします。
機能させるための3つの詳細があります:
- GitHubは、秘密の値がそのまま表示される場合にのみログでマスクします。base32エンコードされた秘密は一致しないため、そのまま出力されます。
permissions: {}は、攻撃者が必要としないジョブのGITHUB_TOKENを制限しますが、シークレットコンテキストは制限しません。- リポジトリにデプロイメント環境がある場合、ツールはそれを
environment: ${{ matrix.environment }}を使用したジョブマトリックスにリストアップするため、しばしば本番環境の認証情報である環境スコープの秘密も出力されます。
秘密情報はGitHub自身のAPIを通じて流出するため、ブロックすべき攻撃者ドメインやアウトバウンド接続はありません。
エンタープライズ組織では、ツールが数分以内に複数のユーザーや自動化アカウントのトークンを循環させ、ワークフローを仕掛ける前にプライベートリポジトリをクローンし、数時間後に同じ組織のクラウド認証情報を使用してAWS Secrets Managerを列挙するのを見ました。
ペイロードの進化
この攻撃の2つのバリアントが並行して観測されています。ブランチ名で区別できます。
ツールA は16進数のサフィックスとプレーンなペイロードを使用します。
ツールB はbase36サフィックスを使用し、最初の実行から数時間後の9月28日に timeout-minutes: 6 と環境マトリックスを追加し、リポジトリごとに選択されたペイロードを変更しました。
10月19日、ツールBはダンプの間に echo X | base32 -w 120 を追加しました。これは LAFA==== をセパレーターとして出力し、おそらくオペレーターのログパーサー用です。数時間後、それは runs-on: self-hosted を持つリポジトリにのみ、おそらく sync-host という名前の2番目のジョブをプッシュしました。これは3つのヘルパーファイル(.gdmp_pat, .gdmp_patg, .gdmp_sweep)を書き込み、各ステージを ===== gdmp-pivot: <stage> ===== ヘッダーの下にログに記録します。
- ホストの詳細とcrontab。
- 31種類のトークン形式(Anthropic, Hugging Face, Groq, NVIDIAなどのAIプロバイダーのキーを含む)、秘密鍵、
.envファイル、Terraform状態、シェル履歴をホームディレクトリ、ワークスペース、システムパスで再帰的に検索します。 /proc/*/environから、すべてのプロセスの環境。- Dockerソケットを介して、ホストのルートファイルシステムをマウントしたコンテナを作成し、ホスト上での検索を繰り返します。
- AWSインスタンスロール認証情報、およびGCPとAzureのメタデータ。
- GitHub ActionsおよびGitLabランナーの認証情報ファイル。
- Kubernetesサービスアカウントトークン。
しかし、このジョブにはバグがあります。間違ったランナーキーファイルを検索し、URL-クレデンシャル正規表現が壊れており、GCPまたはAzureトークンを収集しません。
GitHubの承認保留とプライベートリポジトリ
2026年7月28日以降、GitHubは公開リポジトリで潜在的に悪意のあるワークフロー実行を、共同作業者が承認するまで保留しています。チェックしたすべてのGheist実行(セルフホストジョブを含むすべてのバリアント)は action_required の状態で停止しています。この制御は機能し、悪意のあるペイロードは実行されませんでした。
残念ながら、その保留はプライベートリポジトリやGitHub Enterprise Serverには適用されません。そこでは、GitHub監査ログは ci-sync-* ブランチでの実行が完了し、その後 gheist ユーザーエージェントによって削除されたことを示しています。CloudTrailは、組織自身のワークフローがそれらのブランチで実行され、AWSロールを引き受けていることを示しており、これは承認なしにActionsが実行されたことを証明しています。
防御者にとって、最後のシグナルは、以下の図に示すように、GitHubログなしでGheistを見つけることができます。
同一アカウントでのその他の活動
このキャンペーンは、侵害されたGitHubアクセスを利用しています。同じアカウントは他のアクターやキャンペーンによっても使用されており、侵害された認証情報が脅威アクターのエコシステム全体をどのように移動できるかを示しています。以下のキャンペーンとの重複を観測しました:
-
おとりリポジトリ(マルウェア配布)。 10月6日、391アカウントが約1,461のリポジトリを
fl-studio-crackやsolana-sniper-liteのようなクラックソフトウェアのおとり名に変更しました。このリネームにより、610のci-syncブランチが副作用で消去されました。これらのアカウントの166はGheist活動に一度も出現しないため、プールはGheistのフットプリントよりも大きいです。 -
無料コンピューティング(クリプトマイニング)。 10月18日、25のGheistアカウントがそれぞれ9分以内に「Windows RDP Runner」リポジトリを作成し、GitHub Actionsを無料コンピューティングサイクルに悪用しようとしました。
-
PolinRider。 一部の被害者は、DPRK関連のマルウェアであるPolinRiderに感染しているようです。これはビルド設定ファイルにJavaScriptを隠し、バックデートされたコミットを強制プッシュします。10月19日と20日、3人の被害者は、数百の空白文字の後ろに
vite.config.jsにローダーを付加し、2つのケースではapi.jsを追加して、package.jsonが開発およびビルドの前に実行されるようにして、Gheistコミットを再プッシュしました。 -
Megalodon。 Gheistの最初のフェーズの57アカウントは、5月に行われたMegalodonの被害者でもありました。
追跡できた認証情報ソースは、この状況に合致しています:インフォスティーラーログ、およびTrivyの侵害(3月)のような以前のサプライチェーン侵害で露出したトークンです。
注:GheistはGhostActionとは異なります。GhostActionは異なるワークフローファイルを使用し、秘密情報を193.32.204[.]199に流出させます。
セキュリティチームが取るべき対策
調査
-
ci-sync-という名前のブランチで、6文字のランダムな文字列が続き、唯一の変更が.github/workflows/sync-check.ymlへの新しいファイル追加で、コミットメッセージがci: sync configであるものを探してください。 -
GitHub監査ログで、完了後1分以内に削除された
ci-sync-*ブランチでのワークフロー実行、およびユーザーエージェントgheistからのアクティビティを探してください。 -
ワークフローがOIDCでクラウドに認証する場合、クラウド監査ログで、サブジェクトに
ci-sync-ブランチを含むロールの引き受けやトークン交換を確認してください。これは、GitHubログを収集していなくても、GitHub Actionsが悪意のあるブランチで実行されたことを示します。 -
セルフホストランナーで、ファイル
.gdmp_pat,.gdmp_patg,.gdmp_sweep、およびジョブログ内の文字列gdmp-pivotを探してください。
対応
-
影響を受けたリポジトリで利用可能なすべてのリポジトリ、組織、環境の秘密情報をローテーションしてください。実行またはブランチを削除しても、情報漏洩は元に戻りません。
-
コミットをプッシュしたトークンを失効させ、その所有者のデバイスにインフォスティーラーがないか確認してください。
-
ci-syncブランチがセルフホストランナーで実行された場合、そのホストとそのインスタンスロールは侵害されたと見なしてください。 -
保留中の
sync-check実行を承認しないでください。また、ci-syncブランチからのコードを実行しないでください。
強化
本番環境の秘密情報がある環境ではレビュー担当者を必須とし、OIDC信頼ポリシーを保護されたブランチまたは環境にスコープし、パーソナルアクセストークンではなくGitHub Appsまたは短命な細粒度トークンを使用し、Dockerソケットや無制限のメタデータアクセスなしで、エフェメラルホストとしてセルフホストランナーを実行してください。
侵害の兆候
-
ユーザーエージェント
gheist -
ブランチ
ci-sync-に6文字の文字列が続く、^ci-sync-[0-9a-z]{6}$に一致するもの -
コミットメッセージ
ci: sync configで、.github/workflows/sync-check.ymlのみを追加するもの -
マーカー
toJSON(secrets) }}' | base32 -w 120および===== gdmp-pivot:; ファイル.gdmp_pat,.gdmp_patg,.gdmp_sweep -
ワークフローブロブSHA:
f3da2b8b357dcda02fd455d314be2a95007516a6(プレーン)、d09535857a741bbb976bdc084a9a021713133291(タイムアウト)、1dcaf9cce950aad1eb1546ecce8565b117540c4(セパレーター)、c665b778b2d822453293003e7ca0bbb2cb08e39d(セルフホストジョブ)。環境マトリックスバリアントはリポジトリごとに異なります。
Wizはどのように役立ちますか?
Threat Center advisoryには、仕掛けられたコミット、GitHub監査ログでのGheistアクティビティ、および攻撃者ブランチからのクラウドロールの引き受けをカバーするEvent Explorerクエリが含まれています。Wiz Defendは、「新しいワークフローが短時間で完了して削除された」、「秘密情報ダンプを含むワークフローがプッシュされた」、「既知の悪意のあるコミットメッセージでコミットが作成された」などのルールでアクティビティを検出します。