cicd-pipeline-attack について
CI/CDパイプラインとサプライチェーン攻撃を調べるセキュリティテスター向けの方法論スキルです。意思決定ツリーでプラットフォームの特定、攻撃面の確認、後続の調査経路を整理し、複数のCI/CD環境やシークレット、クラウドへの展開を扱います。
主な機能
- 01一般的なCI/CDプラットフォームの特定
- 02VCSとWebhookの攻撃面の確認
- 03直接・間接的なパイプライン注入の整理
- 04シークレットとクラウド認証情報のリスク評価
- 05プラットフォーム別攻撃経路の参照
活用シーン
- 01CI/CD設定のパイプライン注入リスク確認
- 02リポジトリ、Webhook、ブランチ保護の評価
- 03許可されたテストでのクラウド環境への認証情報リスク追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wgpsec/ aboutsecurity --skill cicd-pipeline-attackインストール後、Claude Code で/cicd-pipeline-attackを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/build-file-injection.mdgithub-actions-abuse.mdplatform-specific.md詳細
CI/CD 流水线与供应链攻击方法论
CI/CD 系统是现代软件工程的核心基础设施——它们拥有代码仓库的读写权限、持有云平台的部署凭据、能够直接修改生产环境。一旦攻陷流水线,攻击者可以同时获得代码控制权、Secrets 访问权和云环境穿透能力,其影响范围远超单台服务器的沦陷。
本技能以决策树形式组织 CI/CD 攻击方法论。各平台的详细技术手法请参阅对应的参考文档。
深入参考
识别到具体平台后,加载对应参考文档获取完整攻击技术细节:
- GitHub Actions 专项攻击手法 → 读 references/github-actions-abuse.md
- Jenkins / Terraform / Atlantis / GitLab CI / Azure DevOps / CircleCI / Drone / Buildkite 等平台 → 读 references/platform-specific.md
- 跨平台构建文件注入(package.json、setup.py、Makefile、Bazel、Maven/Gradle、csproj)→ 读 references/build-file-injection.md
Phase 0: CI/CD 系统识别
在目标代码仓库或基础设施中发现以下标识文件时,可确定对应的 CI/CD 平台:
| 标识文件/特征 | CI/CD 平台 | 下一步 |
|---|---|---|
.github/workflows/*.yml | GitHub Actions | → Phase 2 PPE + 参考 github-actions-abuse.md |
Jenkinsfile 或 /script 控制台 | Jenkins | → Phase 4 Jenkins 专项 + 参考 platform-specific.md |
.gitlab-ci.yml | GitLab CI | → Phase 2 PPE + 参考 platform-specific.md |
.circleci/config.yml | CircleCI | → Phase 2 PPE + 参考 platform-specific.md |
azure-pipelines.yml | Azure DevOps | → Phase 2 PPE + 服务连接 Secret 提取 |
.drone.yml | Drone CI | → Phase 2 PPE + Self-hosted Runner 检查 |
.buildkite/*.yml | Buildkite | → Phase 2 PPE + Agent 云/K8s 权限检查 |
atlantis.yaml + Webhook | Atlantis | → Phase 4 Atlantis 专项 |
*.tf + Terraform Cloud | Terraform Cloud | → Phase 4 Terraform 专项 |
serverless.yml | Serverless Framework | → 参考 platform-specific.md |
docker-compose.yml + CI 触发 | Docker Build | → 检查构建上下文泄露 |
| Airflow DAGs / Concourse pipeline | Airflow / Concourse | → 参考 platform-specific.md |
快速识别技巧:
- 克隆仓库后搜索配置文件:查找
Jenkinsfile、.github/workflows、.gitlab-ci.yml、.circleci、atlantis.yaml - 检查 Webhook 配置:Webhook URL 暴露 CI/CD 服务类型和内网地址
- 枚举 CI/CD 服务端口:Jenkins 默认 8080,Atlantis 默认 4141,GitLab Runner 8093
Phase 1: VCS 攻击面
在进入流水线攻击之前,VCS(版本控制系统)本身就是重要的攻击面。
1.1 代码泄露
代码仓库中常见的敏感信息来源:
- Git 历史记录:已删除的密钥/凭据可能仍在 commit 历史中(
git log -p搜索所有分支) - 公开仓库:使用 GitHub Dork 搜索组织名称 + 关键词(
password、secret、token、AWS_) - 已删除的 Fork 数据:GitHub 上已删除的 fork 中的 commit 数据仍可通过 commit hash 访问
- 内部仓库暴露:private 仓库变 public 前的 fork 数据可通过短 SHA-1 暴力枚举
1.2 分支保护绕过
分支保护是防止恶意代码合入的关键防线,但存在多种绕过方式:
| 绕过场景 | 条件 | 攻击方法 |
|---|---|---|
| 审批不足 | 控制多个账户 | 使用其他账户审批自己的 PR |
| GITHUB_TOKEN 自审批 | Actions 有写权限 | 通过 Actions 中的 GITHUB_TOKEN 审批 PR |
| 推送后审批未失效 | 未启用 "dismiss on push" | 先提交合法代码获得审批,再推送恶意代码 |
| CODEOWNERS 配置错误 | 文件格式有误 | GitHub 不报错但 CODEOWNERS 保护失效 |
| 新分支无保护 | 使用通配符 * 但有延迟 | 创建新分支时分支保护尚未生效,第一次 push 可触发 Actions |
| 管理员豁免 | 管理员未纳入规则 | 管理员可直接绕过所有分支保护 |
| PR 劫持 | 可修改他人 PR | 在他人的 PR 中注入恶意代码后自行审批合并 |
1.3 Webhook 滥用
- 无 Secret 验证:攻击者可伪造 Webhook 请求触发流水线
- Secret 暴露在 URL 中:Secret 附在 URL 参数中,易被日志记录
- IP 白名单绕过:在 GitHub/GitLab 上创建账户配置 Webhook 即可向白名单内的 Jenkins/Atlantis 发送请求
- Bitbucket Cloud:不支持 Webhook Secret,只能依赖 IP 白名单
Phase 2: PPE -- Poisoned Pipeline Execution
PPE 是 CI/CD 攻击的核心框架。攻击者通过修改 CI 配置文件或其依赖文件来"毒化"流水线,使其执行恶意命令。
PPE 判定决策树
是否能写入/修改 CI 配置文件(workflow yml / Jenkinsfile / .gitlab-ci.yml)?
├── 是 → D-PPE(直接毒化)
│ ├── 能直接推送到触发分支 → 最简单路径
│ └── 需要 PR → 检查 PR 是否触发流水线
│
├── 否,但能修改 CI 配置依赖的文件?
│ ├── Makefile / build.sh / package.json / requirements.txt → I-PPE(间接毒化)
│ ├── Terraform .tf 文件 → I-PPE via external data source
│ └── Dockerfile → I-PPE via build context
│
└── 否,且无仓库写权限?
└── 3PE(第三方毒化)
├── 能否提交外部 PR? → pull_request 触发器
├── PR 标题/描述是否被注入到 shell 命令? → Context Script Injection
└── 能否通过 issue/comment 触发? → issue_comment 触发器
D-PPE(Direct PPE)
攻击者直接修改 CI 配置文件。这是最直接的攻击路径:
- 前提:拥有仓库写权限,或能通过 PR 触发使用 PR 分支配置的流水线
- 目标文件:
.github/workflows/*.yml、Jenkinsfile、.gitlab-ci.yml、.circleci/config.yml - 关键条件:某些平台(如 GitHub Actions 的
pull_request触发器)会使用 PR 提交者的 workflow 版本——这意味着攻击者的修改会被执行
I-PPE(Indirect PPE)
攻击者不修改 CI 配置文件本身,而是修改 CI 配置所依赖的文件:
- 构建脚本:
Makefile、build.sh、package.json的scripts字段 - 依赖文件:
requirements.txt、package-lock.json(供应链注入) - IaC 配置:Terraform
.tf文件中的externaldata source 或local-execprovisioner - Docker 构建:控制 Dockerfile 或构建上下文路径
I-PPE 的局限性在于攻击者只能访问流水线原本就加载的 Secrets,无法通过配置声明新的 Secret 引用。
3PE(サードパーティー PPE/パブリック PPE)
リポジトリへの書き込み権限を持たない外部の攻撃者が、以下の方法でパイプラインを実行させます。
コンテキストスクリプトインジェクション(最も一般的):
CI 設定で ${{ github.event.pull_request.title }} などのユーザーが制御可能な式を使用して、run: ステップ内でシェルコマンドを組み立てている場合、攻撃者は PR タイトルからコマンドを注入できます。GitHub Actions は実行前に式をレンダリングするため、シェルの引用符をエスケープしても防御できません。
危険なトリガーの比較:
| トリガー | Secrets へのアクセス | 書き込み権限 | 使用されるコードのバージョン | リスク |
|---|---|---|---|---|
pull_request | なし(GITHUB_TOKEN は読み取り専用) | なし | PR ブランチ | 低(ただし、悪意のある Artifact をアップロードできる可能性があります) |
pull_request_target | あり | あり | ベースブランチ(デフォルトでは安全) | 高(PR コードを checkout すると非常に危険) |
workflow_run | あり | あり | 設定による | 高(連鎖的に悪用されることがよくあります) |
issue_comment | あり | あり | ベースブランチ | 高(PR ref の checkout と組み合わせると RCE が可能) |
pull_request_target の致命的な誤用:
pull_request_target はベースブランチのコンテキストで実行されるため、一見安全に見えます。しかし、workflow で PR のコード(ref: ${{ github.event.pull_request.head.sha }})を明示的に checkout すると、攻撃者のコードが Secrets と書き込み権限を持つ環境で実行されます。
フェーズ 3:Secrets の窃取と横方向への移動
パイプラインの汚染に成功した後の主な目的は、Secrets を窃取し、外部へ展開することです。
3.1 Secrets の抽出方法
環境変数:
env | base64ですべての環境変数をエクスポートします(base64 エンコードにより、GitHub のログマスキングを回避できます)- 二重の base64 エンコードで、さらにマスキングを回避します:
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
ファイルシステム:
- 一時スクリプトファイル:
/home/runner/work/_temp/*(GitHub Actions はレンダリング済みスクリプトを保存します) - プロセスメモリ:
gcoreまたは/proc/<pid>/memを使用して、Runner.Worker/Runner.Listener プロセス内の平文の Secrets を読み取ります
直接持ち出せない場合:
- GITHUB_TOKEN を使用してリポジトリ/issue/comment を作成し、データの中継先として利用します
- Secrets を Artifact に書き込んでアップロードします
- Actions のログに書き込みます(マスキング規則に注意してください)
3.2 CI/CD からクラウド環境への侵入
CI/CD Runner は通常、デプロイ用のクラウドプラットフォームの認証情報を持っています。これらの認証情報が、CI/CD からクラウド環境へ侵入する橋渡しになります。
| 認証情報の取得元 | 場所 | 悪用方法 |
|---|---|---|
| OIDC Token(GitHub → AWS/GCP/Azure) | id-token: write 権限 | OIDC Token を要求 → AssumeRoleWithWebIdentity |
| AWS 静的 AK/SK | 環境変数または Secrets | cloud-aksk-exploit スキルを参照 |
| GCP Service Account JSON | ファイルまたは環境変数 | gcp-pentesting スキルを参照 |
| Azure Service Principal | 環境変数 | aws-pentesting スキル内の Azure 関連の内容を参照 |
| Terraform Cloud Runner 認証情報 | tfc-aws-*/tfc-gcp-* ファイル | CLI を直接使用してクラウドリソースを操作 |
| Kubernetes kubeconfig | ~/.kube/config またはマウントされた SA Token | クラスターの乗っ取り |
| Docker Registry Token | ~/.docker/config.json | 悪意のあるイメージをプッシュ |
セルフホスト Runner の追加の攻撃対象領域:
- クラウドメタデータサービス(169.254.169.254)→ インスタンスにバインドされた IAM ロールの認証情報を取得
- 内部ネットワークへの横方向の移動 → 内部ネットワーク上の他のサービスにアクセス
- Docker API(2375/tcp)→ コンテナーエスケープ
- Kubernetes クラスターへのアクセス → DaemonSet による横方向への拡張
3.3 本番環境の乗っ取り
パイプラインが本番環境へのデプロイを直接担当している場合:
- コードの改ざん:ビルド成果物にバックドアコードを注入します
- サプライチェーン攻撃:npm/PyPI パッケージの公開プロセスを改ざんします(publish token を窃取 → 悪意のあるバージョンを公開)
- イメージの汚染:Docker イメージのレイヤーを変更して悪意のあるコードを注入します
- IaC の改ざん:Terraform/CloudFormation 設定を変更してバックドアリソースを作成します
フェーズ 4:プラットフォーム固有の攻撃
4.1 GitHub Actions
GitHub Actions は最も広く利用されている CI/CD プラットフォームの一つであり、攻撃対象領域が広範です。
- Artifact のポイズニング:低権限の workflow が悪意のある Artifact をアップロード → 高権限の workflow がダウンロードして実行
- Cache のポイズニング:workflow 間で共有されるキャッシュに信頼境界がない → キャッシュ内のスクリプト/バイナリファイルを汚染
- GITHUB_TOKEN の悪用:PR のマージ、PR の承認、PR の作成
- Action タグの乗っ取り:攻撃者が Action リポジトリへの書き込み権限を取得した後、タグを force-push して悪意のある commit を指すように変更
- AI エージェントのインジェクション:CI 内の LLM エージェント(Gemini/Claude Code Action)は、プロンプトインジェクションによって制御される可能性があります
→ references/github-actions-abuse.md を参照
4.2 Jenkins
Jenkins は高い権限を持つため、価値の高い標的となります。
- Groovy Script Console(
/script)→ 直接 RCE - Pipeline の作成/変更 → Jenkinsfile を介して任意のコマンドを実行
- 認証情報のダンプ → Groovy スクリプトで credentials.xml 内のすべての秘密鍵をエクスポート
- ファイル読み取り → RCE →
master.keyとhudson.util.Secretを読み取り → すべての認証情報をオフラインで復号 → remember-me Cookie を偽造
→ references/platform-specific.md を参照
4.3 Terraform / Atlantis
IaC ツールへの攻撃の中核は、コードが実行される点にあります。
- Terraform Plan RCE:
externalデータソースまたは悪意のある Provider は、planフェーズでコードを実行できます - Terraform Apply RCE:
local-execprovisioner がapplyフェーズで実行されます - State ファイルの改ざん:state ファイルに悪意のある provider を注入 → 次回の plan/apply で RCE が発生
- Atlantis Plan のインジェクション:PR で
.tfファイルを変更してatlantis planを実行 → Atlantis サーバー上で RCE - Atlantis Custom Workflow:
allow_custom_workflows=trueの場合、atlantis.yamlで任意の実行ステップを定義できます - Terraform Cloud Speculative Plan:TFC Token を窃取 → speculative plan を実行 → Runner 上でコードを実行 → 注入されたクラウド認証情報を取得
→ references/platform-specific.md を参照
4.4 其他平台速查
| 平台 | 关键攻击路径 | 详情 |
|---|---|---|
| GitLab CI | Runner Token 窃取、共享 Runner 逃逸、CI 变量注入 | → platform-specific.md |
| CircleCI | Context Secrets 窃取、SSH Rerun、项目变量导入 | → platform-specific.md |
| Azure DevOps | Service Connection Secret、变量/参数注入、Runner hijack | → platform-specific.md |
| Drone CI | .drone.yml commands 注入、Self-hosted Runner 云/K8s 权限 | → platform-specific.md |
| Buildkite | .buildkite/*.yml command 注入、Agent 所在云/K8s 权限 | → platform-specific.md |
| Serverless Framework | IAM Role 提权(默认 AdministratorAccess)、Plugin 投毒 | → platform-specific.md |
| CloudFlare | Workers 滥用、Zero Trust 绕过 | → platform-specific.md |
| Concourse / Airflow | 参考 platform-specific.md 快速参照表 | → platform-specific.md |
注意事项
操作安全:
- CI/CD 系统通常有完整的审计日志——PR 创建、workflow 执行、Secrets 访问都会被记录
- GitHub 上的 PR 即使删除账户后仍可能被 SIEM 捕获
- Self-hosted Runner 上的操作可能触发 EDR/HIDS 告警
- 在授权测试中应事先与客户确认 CI/CD 测试范围和影响
Secrets 保护绕过:
- GitHub Actions 日志掩码只保护渲染输出,进程内存中仍存在明文
- 使用 base64 编码或加密可绕过大多数自动掩码机制
- JWT 签名值等派生数据不会被掩码
供应链攻击升级:
- 窃取到 npm/PyPI publish token 后可发布恶意包版本
- npm 的
preinstall/postinstallhook 在安装时自动执行 - Python 的
.pth文件在解释器启动时自动执行 - 单个 CI/CD 沦陷可能级联影响整个供应链(参考 tj-actions/Ultralytics 事件)