Skip to main content

cicd

CI/CD pipeline attack category — poisoned pipeline execution, GitHub Actions expression injection, self-hosted runner abuse, secrets/OIDC exfil. Routing skill: fingerprint the CI provider + workflow surface, then load the matching leaf.

Datos de origen

Repositorio
BitterSecurity/Decepticon
Última actividad en el origen
1 de junio de 2026 a las 23:04
Idioma detectado de SKILL.md
inglés
Estrellas
5666
Forks
1067

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
5 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
cicd
description
CI/CD pipeline attack category — poisoned pipeline execution, GitHub Actions expression injection, self-hosted runner abuse, secrets/OIDC exfil. Routing skill: fingerprint the CI provider + workflow surface, then load the matching leaf.
allowed-tools
Bash Read Write
metadata
{"subdomain":"reconnaissance","when_to_use":"ci cd pipeline github actions gitlab ci jenkins circleci buildkite drone azure devops travis workflow runner secrets oidc ppe pipeline injection","tags":"ci-cd, supply-chain, pipeline, github-actions, runner","mitre_attack":"T1195, T1199, T1078, T1554"}
# CI/CD Pipeline Exploitation — Category Overview Routing skill for attacks against build / deployment pipelines. Pipelines run attacker-influenced code (PRs, dependencies, build scripts) with privileged tokens, cloud OIDC, and write access to artifacts that downstream consumers trust. Compromise of a single pipeline often equals compromise of every release built by it. ## Sub-Skills | Sub-Skill | Covers | When to Load | |---|---|---| | **poisoned-pipeline-execution** | Direct + Indirect PPE: injecting commands via attacker-controllable build files (`Makefile`, `package.json` scripts, `build.gradle`, `Dangerfile`, `.pre-commit-config.yaml`), `pull_request_target` abuse, fork-PR build triggers, dependency/test-script execution. | Target builds untrusted PR code; you can land a malicious file or dependency. | `load_skill("/skills/standard/exploit/cicd/poisoned-pipeline-execution/SKILL.md")` | | **github-actions-injection** | `${{ }}` template injection via untrusted context (issue/PR title, body, branch name, commit message) into `run:` steps, `pull_request_target` + PR-head checkout, `GITHUB_TOKEN` permission abuse, artifact/cache poisoning, action pinning (tag vs SHA). | Target uses GitHub Actions and accepts external contributors. | `load_skill("/skills/standard/exploit/cicd/github-actions-injection/SKILL.md")` | | **self-hosted-runner-abuse** | Non-ephemeral runner persistence, fork-PR job execution on self-hosted, runner-label targeting, secret theft from runner env, lateral movement into internal network / cloud metadata. | Target advertises self-hosted runners (workflow `runs-on:` label or public job logs). | `load_skill("/skills/standard/exploit/cicd/self-hosted-runner-abuse/SKILL.md")` | | **cicd-secrets-exfil** | Extracting CI secrets / OIDC tokens: `echo` / `printenv` exfil, masking bypass (base64, char-split), OIDC -> cloud role assumption, `GITHUB_TOKEN` / `CI_JOB_TOKEN` scope abuse, cache / artifact secret leakage. | You already have code execution in a CI job; need to convert it into durable cloud / registry access. | `load_skill("/skills/standard/exploit/cicd/cicd-secrets-exfil/SKILL.md")` | ## Provider fingerprinting ```bash # GitHub Actions ls -la <REPO>/.github/workflows/ 2>/dev/null gh api "repos/<OWNER>/<REPO>/actions/workflows" --jq '.workflows[] | {name,path,state}' # GitLab CI test -f <REPO>/.gitlab-ci.yml && echo "GitLab CI" ls <REPO>/.gitlab/ci/ 2>/dev/null # Jenkins test -f <REPO>/Jenkinsfile && echo "Jenkins"; find <REPO> -name 'Jenkinsfile*' -type f # CircleCI / Buildkite / Drone / Azure / Travis for f in .circleci/config.yml .buildkite/pipeline.yml .drone.yml azure-pipelines.yml .travis.yml; do test -f "<REPO>/$f" && echo "$f" done # Provider hints in README / badges grep -RhoE 'github\.com/[^/]+/[^/]+/actions|gitlab\.com/[^/]+/[^/]+/-/pipelines|circleci\.com/gh/|app\.travis-ci\.com' <REPO> 2>/dev/null | sort -u ``` ## Workflow file recon (GitHub Actions example) ```bash # Local checkout find <REPO>/.github/workflows -type f \( -name '*.yml' -o -name '*.yaml' \) -print # Remote, no clone needed gh api "repos/<OWNER>/<REPO>/contents/.github/workflows" --jq '.[].name' # Pull every workflow at HEAD for wf in $(gh api "repos/<OWNER>/<REPO>/contents/.github/workflows" --jq '.[].path'); do echo "=== $wf ===" gh api "repos/<OWNER>/<REPO>/contents/$wf" --jq '.content' | base64 -d done ``` ## Risky-surface triage | Signal | Why it matters | Grep | |---|---|---| | `pull_request_target:` trigger | Runs with write `GITHUB_TOKEN` + secrets while checking out attacker code | `grep -rE '^\s*pull_request_target\s*:' .github/workflows/` | | `actions/checkout` with `ref: ${{ github.event.pull_request.head.sha }}` under `pull_request_target` | Pulls attacker code with privileged context | `grep -rE 'pull_request\.head' .github/workflows/` | | `${{ github.event.* }}` interpolated into a `run:` block | Expression injection sink (issue/PR body, title, branch name, commit msg) | `grep -rE '\$\{\{\s*github\.event\.(issue\|pull_request\|comment\|head_commit)' .github/workflows/` | | `runs-on: [self-hosted, ...]` on public repo | Self-hosted runner reachable from fork PRs | `grep -rE 'runs-on:\s*(\[\s*self-hosted\|self-hosted)' .github/workflows/` | | Third-party action pinned by tag (`@v3`) instead of SHA | Action repo / tag retargeting → silent supply-chain | `grep -rE 'uses:\s*[^/]+/[^@]+@v?[0-9]' .github/workflows/` | | `permissions:` block missing or `write-all` | Token over-scoped; abuse to push to protected branches, publish releases | `grep -rE 'permissions:|write-all' .github/workflows/` | ## Secret-exposure surface ```bash # Secrets and OIDC references — every line is a potential exfil target once you have RCE in a job grep -rnE 'secrets\.|vars\.|env\.[A-Z_]+_TOKEN|env\.[A-Z_]+_KEY|id-token:\s*write|configure-aws-credentials|google-github-actions/auth' .github/workflows/ # Exposed in public job logs (replays) gh run list --repo <OWNER>/<REPO> --limit 20 --json databaseId,name,status,conclusion gh run view <RUN_ID> --repo <OWNER>/<REPO> --log | grep -iE 'token|secret|password|aws_|gcp_|azure_' | head ``` ## Tooling | Tool | Use | |---|---| | `gh` (GitHub CLI) | Recon, workflow listing, run/log inspection, PR creation | | `gato` / `gato-x` (praetorian-inc) | GitHub Actions attack toolkit — self-hosted runner enum, PPE, secret exfil chains | | `actionlint` | Local lint that flags many injection sinks — defenders use it; you can read its rules to find sinks | | `octoscan` / `zizmor` | Static scanners for GitHub Actions security issues | | `tj-actions-changed-files` CVE class (CVE-2025-30066) | Known compromised-action precedent; pattern to look for in any third-party action | | Burp Collaborator / `interactsh` | DNS / HTTP beacon for non-destructive PoC of code execution on a runner | ## Decision gate Before any active test, confirm in writing: 1. The target program explicitly allows CI/CD testing (many programs scope this out — "infrastructure", "third-party CI" exclusions are common). 2. PoC will use a **beacon-only** payload (DNS / HTTP callback). Do not exfiltrate real secrets to attacker-controlled storage; print the first 4 chars of a token to prove access, then stop. 3. Any malicious branch / PR / fork is clearly labeled `security-research` and is deletable on request. 4. You will not push to protected branches, publish artifacts, or assume cloud roles. Prove the *capability*, do not exercise it. ## Cross-references - Supply-chain catalog: `/skills/standard/exploit/supplychain/SKILL.md` - OPSEC + scope discipline: `/skills/shared/opsec/SKILL.md` - Cloud OIDC follow-on: cloud / IAM enumeration skills after a successful OIDC token exchange
Ver en GitHub