盗まれた GitHub トークンで不正ワークフローを足されても気付く(Gheist の手口と検知点)
Gheist はインフォスティーラー等で盗んだトークンで不正ブランチとワークフローを追加し、シークレットを Base32 で符号化してログのマスクをすり抜け、API でログを回収して数秒で実行履歴を消す。公開リポジトリは自動保留で止まったが、非公開リポジトリと GHES では成功している。
観測された手口(Wiz Research)
- 9 月 15 日から追跡。850 超の侵害アカウントから 1 万 3500 超の不正ブランチを回収。出どころが追えたトークンはインフォスティーラーのログや過去のサプライチェーン侵害由来。
- ワークフローはシークレットを Base32 で符号化して出力し、GitHub のログマスクを回避。攻撃者は API でログを取得し、実行完了から 1 分以内に履歴を削除。攻撃者固有の外部通信先は使わない(外向き通信の監視では見えにくい)。
- 10 月 19 日以降の変種は、セルフホステッドランナーのホストからトークン、秘密鍵、環境変数、AWS インスタンスロールの認証情報を探すジョブを追加。
- 公開リポジトリでは GitHub の自動保留機能が全実行を止めた。非公開リポジトリや GitHub Enterprise Server は自動保留の対象外で、実行成功と後続の活動が観測された。
検知の手掛かり
- 監査ログ・API ログの User-Agent
gheist ci-sync-に英数字 6 文字が続くブランチ名、sync-check.yml- 実行完了から 1 分以内のワークフロー実行履歴の削除
- OIDC を使っている環境では、当該ブランチを主体とするロール引き受け(AWS CloudTrail の
AssumeRoleWithWebIdentityなど)をクラウド監査ログで確認
対応・予防
- コミットに使われたトークンを失効し、影響リポジトリから使える全シークレットを交換する。
- 保留された実行は承認しない。
- 不正ジョブが動いたセルフホステッドランナーは、ホストとインスタンスロールを侵害済みとして扱う(作り直し・ロールの認証情報の無効化)。
- 予防は 使い捨てブランチへの push で CI のシークレットを抜く手口に備える(LiteLLM 侵害の教訓) と同じ:Environment のデプロイ可能ブランチ制限、
.github/workflows/**変更へのレビュー必須、OIDC の信頼条件をref:refs/heads/mainなど特定ブランチに絞る。 - 開発端末のトークンがインフォスティーラーで抜かれるのが入口なので、PAT は fine-grained・短期限にし、端末側の対策(インフォスティーラーに AI ツールと開発環境の認証情報を抜かれる前提で備える(Aokigahara))も合わせる。