Threat Advisory April 3, 2026

TeamPCP Supply Chain Attack

Executive Briefing by Exposure Security • Event Timeframe: March 2026

Executive Summary

In March 2026, a threat group called TeamPCP compromised four widely-used developer tools (Trivy, Checkmarx KICS, LiteLLM, and Telnyx) in a cascading supply chain attack that may have left credentials in attacker hands across an estimated 500,000+ machines. Each compromise enabled the next, so understanding the full sequence is essential to assessing your exposure and deciding where to act. A concurrent attack on the axios npm package occurred in the same period but was attributed to a separate, unrelated threat actor; it's referenced in the Appendix.

Why It Matters

Your cloud credentials, API keys, and secrets may already be in attacker hands if you used Trivy, Checkmarx KICS, LiteLLM, or Telnyx during March 2026.

  • Attackers compromised these widely-used developer tools and security scanners, injecting code that silently stole credentials from anyone that downloaded or ran them.
  • This cascaded into what security researchers described as one of the largest CI/CD (Continuous Integration/Continuous Delivery) supply chain attacks on record, affecting four package ecosystems and an estimated 500,000+ machines.
  • CISA has added this vulnerability to its Known Exploited Vulnerabilities catalog.
  • Federal agencies must remediate by April 8, 2026.
  • Private organizations should treat this as a benchmark deadline.
  • Many common defenses wouldn't have prevented these attacks from succeeding.
  • See the Full Analysis and Recommendations section for more detail.

Impact

According to Wiz and BreachForums reporting, the attackers (TeamPCP) are partnering with multiple ransomware and extortion groups to monetize stolen credentials. Per Mercor's public disclosure, the first confirmed victim, an AI recruiting startup, lost 4TB of data including source code, customer databases, and identity documents.

Key Actions

  • Audit all CI/CD pipelines and development environments for exposure to compromised packages during the affected windows (see Attack Timeline in the Full Analysis section): Trivy (March 19-21), Checkmarx KICS (March 23-24), LiteLLM versions 1.82.7 and 1.82.8 (March 24-25), and Telnyx versions 4.87.1 and 4.87.2 (March 27). Also audit for CanisterWorm-infected npm packages in the @emilgroup, @opengov, and @v7 namespaces.
  • Rotate all credentials immediately if your build systems ran any affected package; don't wait for forensic confirmation of a breach. Rotating everything simultaneously ("atomically") is the ideal; if that's not feasible, work through the Credential Rotation Checklist in the Appendix in priority order, moving as fast as possible. The completeness of the rotation matters more than the method: one missed service account is all an attacker needs, as the Trivy incident demonstrated.
  • Check GitHub accounts for unauthorized repositories named tpcp-docs or docs-tpcp. Check Docker Hub for unexpected image tags without corresponding GitHub releases. These are exfiltration artifacts created by the malware using stolen tokens.

If you're unsure whether you used any of the affected packages, ask your DevOps or engineering lead to check CI/CD pipeline logs for the date ranges and package names above. For most organizations this is a one-day task; larger organizations with many pipelines should budget more time.

Important Notes

  • No new compromised packages have been identified since early April, but FBI reporting indicates approximately 300GB of stolen data (environment variables, API keys, cloud credentials, and CI/CD secrets) are actively being distributed and monetized via BreachForums and ransomware partnerships.
  • Post-incident analysis suggests organizations that caught this early did so through runtime network monitoring of their build systems, not through code review or package scanning. See the Defense Efficacy Table in the Full Analysis section.
  • Cyber insurance: notify your carrier promptly if you confirm exposure. Many policies require notification within 72 hours of a known incident. Credential theft and subsequent ransomware from the same campaign may be treated as separate events under your policy; confirm this with your broker before closing the incident.
  • Board communication: if you confirm exposure, this warrants board-level notification. Key points: what data or credentials may have been taken; 300GB of stolen data are actively circulating on criminal forums; the estimated remediation timeline (typically 1-3 business days for full credential rotation, plus time to check for signs of attacker presence); and whether your cyber insurance policy covers the response.
  • Third-party and vendor exposure: if a vendor, contractor, or managed service provider runs any of the affected tools in pipelines with access to your environment, your credentials may be at risk without your own pipelines being affected. Verify with key vendors that they have audited their exposure and rotated any credentials used in your environment.
  • Law enforcement: organizations that have confirmed data exfiltration, are critical infrastructure, or are federal contractors should consider notifying the FBI (Internet Crime Complaint Center, ic3.gov) or CISA's 24/7 reporting line (cisa.gov/report). This is separate from insurance notification and may be mandatory for some sectors.
  • Regulatory references, CVE details, and indicators of compromise (IOCs) are in the Appendix.

Full Analysis and Recommendations

Threat Actor Background

TeamPCP (also tracked as UNC6780 by Google/Mandiant, and as PCPcat, ShellForce, and DeadCatx3 by other researchers) has been active since at least September 2025. The group first gained wider attention in December 2025 through exploitation of the React2Shell vulnerability (CVE-2025-55182), which enabled remote code execution in vulnerable cloud endpoints. The group initially focused on ransomware and cryptocurrency theft before pivoting to supply chain compromise operations starting in mid-March 2026.

As of late March, TeamPCP has announced partnerships with three criminal groups: the LAPSUS$ extortion group (confirmed by Wiz, March 30), the Vect ransomware group (announced on BreachForums, April 1), and CipherForce ransomware. The group maintains an active Telegram channel and a leak site, and has publicly announced at least 16 confirmed organizational compromises as of late March 2026. The shift toward supply chain operations appears strategic: by compromising trusted developer tools, TeamPCP gains access to credentials from thousands of downstream organizations without compromising each one individually.

Attack Timeline

The following table traces the campaign from initial breach through the most recent known activity.

Date Event
Late Feb 2026 An automated bot, hackerbot-claw, exploits a pull_request_target workflow misconfiguration in Aqua Security's Trivy repository, stealing a privileged Personal Access Token (PAT). Aqua Security rotates most credentials but doesn't rotate the aqua-bot service account password. The bot account Argon-DevOps-Mgt retains write and admin access across both public and internal GitHub organizations.
Mar 19 (Trivy) TeamPCP exploits the retained access to force-push malicious binaries to 76 of 77 version tags in aquasecurity/trivy-action and all tags in aquasecurity/setup-trivy. Also pushes malicious Trivy binary v0.69.4. Malware (kamikaze.sh) runs before legitimate scan logic, then allows the scanner to continue normally; build pipelines return clean status while silently exfiltrating credentials. Primary C2: scan.aquasecurtiy[.]org (typosquat of aquasecurity.org). Backup C2: ICP decentralized infrastructure. CVE-2026-33634 (CVSS 9.4) assigned. .
Mar 19 Using npm publishing tokens stolen during the Trivy compromise, TeamPCP seeds CanisterWorm (a self-propagating npm worm) into 47+ packages across the @emilgroup, @opengov, and @v7 namespaces. The worm uses a decentralized Internet Computer Protocol (ICP) C2 that can't be taken down via conventional requests. .
Mar 19-21 Malicious Trivy binaries downloaded by an estimated 500-1,000+ organizations. TeamPCP also pushes malicious Docker Hub image tags 0.69.5 and 0.69.6 with no corresponding GitHub releases (a key detection indicator).
Mar 21 Aqua Security detects the compromise and begins takedown. Malicious artifacts remain accessible for approximately 48 hours while mirrors clear. TeamPCP pushes additional malicious Docker images 3 days into remediation, demonstrating access still hadn't been severed.
Mar 23 (Checkmarx) TeamPCP uses Trivy-stolen GitHub PATs to compromise Checkmarx. Force-pushes malicious commits to all 35 version tags of checkmarx/kics-github-action and poisons version 2.3.28 of checkmarx/ast-github-action. C2: checkmarx[.]zone. TeamPCP posts to their Telegram channel: "These companies were built to protect your supply chains yet they can't even protect their own..." .
Mar 23 CanisterWorm's destructive wiper component activates, targeting Iranian infrastructure by deploying privileged Kubernetes DaemonSets to brick clusters and executing recursive file deletions on non-containerized hosts.
Mar 24 (LiteLLM) TeamPCP uses PyPI publishing tokens stolen from Trivy victims to publish poisoned LiteLLM packages v1.82.7 and v1.82.8. Version 1.82.8 uses a highly evasive .pth file (litellm_init.pth) dropped into Python's site-packages. Python auto-executes .pth files on every interpreter startup, meaning the malware triggers even if LiteLLM is never imported. Simply running python --version activates it. C2: models.litellm[.]cloud. ; .
Mar 25 Wiz publishes technical analysis confirming shared C2 infrastructure (checkmarx[.]zone) across Trivy and Checkmarx compromises, attributing the campaign to TeamPCP. .
Mar 27 (Telnyx) TeamPCP publishes poisoned Telnyx Python SDK versions 4.87.1 and 4.87.2, using WAV steganography to hide encrypted second-stage payloads inside audio files (hangup.wav on Windows, ringtone.wav on Linux/macOS) to bypass network filters. Establishes persistence across Windows, Linux, and macOS.
Mar 28 CISA adds CVE-2026-33634 to the Known Exploited Vulnerabilities (KEV) catalog. Federal remediation deadline: April 8, 2026. .
Mar 29 Singapore Cyber Security Agency (CSA) publishes advisories AD-2026-001 (TeamPCP/Trivy/Checkmarx) and AD-2026-002 (a separate, concurrent axios supply chain attack attributed to a North Korean threat actor). .
Mar 30 , TeamPCP is collaborating with the LAPSUS$ extortion group to monetize stolen credentials. According to FBI reporting, approximately 300GB of stolen data (environment variables, API keys, cloud credentials, and CI/CD secrets) had been distributed to roughly 300,000 BreachForums users. .
Mar 31 Mercor, an AI recruiting startup, discloses a breach traced to the TeamPCP campaign via a compromised Tailscale VPN credential (a credential stolen by the malware from another victim, not a Tailscale product vulnerability). , stolen data includes 939GB of source code, 211GB of user database records (email addresses and hashed passwords), and approximately 3TB of video interviews and passport images, totaling 4TB. .
Apr 1 TeamPCP announces additional ransomware partnerships: the Vect ransomware group (on BreachForums) and CipherForce. No new compromised packages identified since this date, but stolen data continues to be distributed and monetized.
Apr 2-present No new compromised packages identified. Credential monetization, ransomware partnership activity, and extortion operations continue.

What These Tools Do

The four compromised tools span different parts of the software development lifecycle. Understanding what they do and what credentials they can access explains why their compromise was so damaging:

  • Trivy is an open-source vulnerability scanner made by Aqua Security, widely used in CI/CD pipelines to check container images and application dependencies for known security issues. Because it runs inside build environments with elevated access, it can reach all secrets and credentials used during the build process: cloud provider keys, registry tokens, and any environment variables defined in the pipeline.
  • Checkmarx KICS (ast-github-action and kics-github-action) are GitHub Actions used to scan infrastructure-as-code files (Terraform, Kubernetes manifests, Dockerfiles) for misconfigurations. Like Trivy, they run inside build workflows with access to repository secrets and environment variables.
  • LiteLLM is a popular open-source Python library providing a unified interface for calling multiple AI model APIs (OpenAI, Anthropic, Azure, and others). The compromised PyPI package used a .pth file that executed on every Python interpreter startup, before any application code ran, giving it access to all environment variables in the running process including AI API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, and others), database credentials, and secrets loaded by the application.
  • Telnyx Python SDK is the official client library for the Telnyx communications platform (voice, SMS, SIP). The compromised versions executed immediately on import, collecting environment variables, SSH keys, and cloud credentials from the running process.

Root Cause: Misconfigured GitHub Action (Complicated by Incomplete Credential Rotation)

The initial access vector was a known dangerous GitHub Actions misconfiguration. In late February 2026, an automated bot (hackerbot-claw) exploited a pull_request_target workflow in Aqua Security's Trivy repository, a configuration that grants write permissions to code from external contributors, enabling privilege escalation through pull request workflows. The bot stole a privileged Personal Access Token. This misconfiguration had been flagged by automated tooling in November 2025, over three months before exploitation.

Aqua Security discovered the breach, publicly disclosed it on March 1, and rotated credentials. The rotation wasn't complete, however. The aqua-bot service account password wasn't changed. Per Aqua's own post-incident report, the rotation wasn't atomic and attackers may have retained access to refreshed tokens. The attacker retained access through the bot account Argon-DevOps-Mgt, which had write and admin access across both public and internal GitHub organizations.

Aqua knew they were compromised and acted, but the incomplete execution of credential rotation allowed TeamPCP to retain the access needed to launch the March 19 campaign. When TeamPCP struck again, they were using credentials that had survived a deliberate but incomplete remediation.

How the Malware Worked

TeamPCP introduced several technically notable techniques across the campaign. Understanding them is relevant for detection and for evaluating whether your security controls would have caught the activity.

Credential Theft and Encryption

The primary payload (called SANDCLOCK by Google/Mandiant, and TeamPCP cloud stealer by Unit 42/Palo Alto Networks) is one of the most comprehensive credential harvesters observed in a supply chain attack. It collects SSH keys, cloud provider credentials (AWS, GCP, Azure), Kubernetes secrets, .env files, database configs, TLS private keys, shell history, Git credentials, Docker credentials, CI/CD pipeline configs, HashiCorp Vault tokens, cryptocurrency wallet keys, and VPN configurations, among others.

Critically, exfiltrated data is encrypted using AES-256-CBC with a hard-coded 4096-bit RSA public key before transmission. This means that even if you intercept the network traffic or find a cached copy of the exfiltration archive (tpcp.tar.gz), you can't recover the stolen credentials without the attacker's private key. It's therefore impossible to determine precisely which credentials were taken by inspecting network logs alone.

CanisterWorm: Self-Propagating npm Worm

Using npm publishing tokens stolen during the Trivy compromise, TeamPCP seeded CanisterWorm into 47+ npm packages. The worm operates in four stages:

  • A postinstall hook in the malicious package.json runs automatically on every npm install, requiring no user action. It immediately hunts for npm tokens in .npmrc files, environment variables, and live npm config.
  • A base64-encoded Python script is decoded and installed as a systemd user service named pgmon, designed to look like a legitimate PostgreSQL monitoring tool. It requires no root access.
  • Rather than a conventional web server, the backdoor polls an Internet Computer Protocol (ICP) canister: decentralized blockchain infrastructure with no single host, meaning it can't be taken down via conventional law enforcement or hosting provider requests. The attacker can update payloads at any time without modifying the infected npm packages.
  • A detached process authenticates with each stolen npm token, enumerates every package that token can publish to, bumps the patch version, and republishes the worm under the victim's package name with the —tag latest flag. The victim unknowingly spreads the worm to their own users.

CanisterWorm also integrated a destructive wiper component, observed March 23, 2026 targeting Iranian infrastructure. The wiper deploys privileged Kubernetes DaemonSets to brick entire clusters, or executes recursive file deletions on non-containerized hosts.

LiteLLM: The .pth File Technique

Rather than a postinstall hook (which defenders are increasingly aware of), LiteLLM version 1.82.8 used a .pth file (litellm_init.pth) dropped into Python's site-packages directory. Python automatically executes .pth files on every interpreter startup, regardless of what Python program is running. This means the malware activated even if LiteLLM was never imported; simply running python —version was sufficient to trigger it. This technique bypasses nearly all supply chain scanning tools, which focus on setup.py and __init__.py but not .pth files.

Telnyx: WAV Steganography

The Telnyx compromise used WAV steganography to hide encrypted second-stage payloads inside valid audio files. The malicious packages embedded payloads in hangup.wav (Windows) and ringtone.wav (Linux/macOS). Because the files are valid audio files, they pass most network filters and endpoint detection tools that look for suspicious binary formats, allowing the attacker to deliver platform-specific payloads that appear to be audio data to any security tool inspecting network traffic.

The Backdoor: Persistent Remote Access

Once credentials are stolen, the malware installs a persistent backdoor (sysmon.py) as a systemd service (sysmon.service) described as "System Telemetry Service", designed to look like a legitimate monitoring agent. Key behaviors:

  • Sleeps for 5 minutes on startup to avoid behavioral detection tools that watch for immediate network activity after a new process starts.
  • Every 50 minutes, fetches a URL from checkmarx[.]zone/raw using a generic browser User-Agent header. If the response is a YouTube URL, the backdoor does nothing; this is the attacker's dormancy signal, making the beaconing traffic appear benign when no active campaign is running.
  • When an active payload URL is received, downloads the binary to /tmp/pglog, sets it executable, and launches it as a fully detached process. Records the executed URL to /tmp/.pg_state to avoid re-execution.
  • The backdoor can lie dormant for months before being activated, giving the attacker ongoing arbitrary code execution across all infected hosts without burning C2 infrastructure.

Kubernetes Lateral Movement

If the malware runs inside a Kubernetes pod with a permissive service account, it escalates from credential theft to full cluster compromise. It creates a privileged pod in the kube-system namespace on every node (including control plane nodes) with the host filesystem mounted at /host. It then uses chroot /host to write the backdoor directly onto the underlying host filesystem and installs it as a system-level systemd service, so it survives container restarts. A single compromised container with a permissive service account becomes full compromise of every node in the cluster.

Threat Actor Evolution

TeamPCP has evolved from a ransomware and cryptocurrency theft operation into what researchers call an Initial Access Broker (IAB), meaning an attacker that specializes in breaking into organizations and selling that access to other criminal groups:

  • LAPSUS$ Partnership: According to Wiz's March 30 analysis, TeamPCP is collaborating with the LAPSUS$ extortion group to monetize stolen credentials.
  • Vect Ransomware: TeamPCP announced a partnership with the Vect ransomware group on BreachForums, allowing TeamPCP to concentrate on supply chain operations while Vect handles ransomware deployment.
  • CipherForce Partnership: TeamPCP also announced a partnership with CipherForce ransomware. As of late March, CipherForce's site listed 16 confirmed TeamPCP victims with countdown timers to data publication.
  • Credential Distribution: According to FBI reporting, approximately 300GB of stolen data (environment variables, API keys, cloud credentials, and CI/CD secrets) are being distributed to roughly 300,000 BreachForums users.
  • First Confirmed Victim: According to Mercor's public disclosure, the company lost 4TB of stolen data: 939GB of source code, 211GB of user database records (email addresses and hashed passwords), and approximately 3TB of video interviews and passport images. Initial access was via a compromised Tailscale VPN credential sourced from the TeamPCP credential stockpile. This was a credential stolen by the malware from another victim, not a Tailscale product vulnerability.

Defense Efficacy

This campaign was designed to defeat many common defensive controls by operating through legitimate, trusted maintainer credentials and infrastructure. The table below assesses each control hypothetically (whether it would have stopped or limited this attack if deployed) based on post-incident analysis. It doesn't assert that you had or lacked these controls.

Defense Efficacy Table

Defense / Measure Assessment Why
Code review (human inspection of changes before merging) Would Not Help TeamPCP used compromised maintainer credentials, so changes appeared to come from trusted developers and passed review gates.
Tag pinning (using version tags such as @v2 to reference specific releases) Would Not Help 76 of 77 trivy-action release tags were force-pushed to malicious commits. Tags are mutable pointers, not immutable identifiers.
SHA pinning (pinning to a specific commit hash) Would Partially Help SHA pinning would have protected against the tag-swap attack. However, GitHub's fork-commit resolution allows an attacker-controlled fork commit to be reachable by SHA from the parent repo, meaning SHA pinning alone isn't foolproof without branch verification.
Package lockfiles (files that record exact dependency versions so every install uses the same packages, for example package-lock.json or Pipfile.lock) Would Not Help Lockfiles pin package versions but not artifact content. Compromised builds can produce different binaries from the same version tag.
Domain reputation filtering Would Not Help All C2 domains were newly registered typosquats of legitimate project domains (for example, scan.aquasecurtiy[.]org mimicking aquasecurity.org). No prior reputation signal existed.
Dependency scanning / Software Bill of Materials (SBOM) review Would Partially Help Scanning would have identified affected versions, but only after public disclosure. Pre-disclosure, all packages appeared legitimate and were signed by known maintainers.
Runtime network monitoring (watching what your build systems connect to outbound) Would Help Organizations monitoring outbound connections from build systems detected malicious C2 beaconing before credentials were fully exfiltrated. This was the primary detection vector for early responders.
Artifact attestation (verifying that a binary was built from a known source commit) Would Help Attestation would have caught the mismatch between the signed tag and the force-pushed malicious binary (the most reliable pre-disclosure control). It's now a CISA-recommended control for CI/CD environments.
Isolated build environments with scoped credentials (builds run in sandboxes with credentials restricted to that specific job only) Would Help Build environments holding only scoped credentials (minimum permissions needed for each job, no access to production systems) limited the blast radius significantly. Organizations with broad-access build credentials lost far more. To implement: use separate service accounts per pipeline, grant only the permissions each job requires, and never inject production credentials into build environments.
Blocking outbound internet access from build environments (allowlist-only egress) Would Help Build environments with outbound allowlists would have prevented C2 beaconing and blocked exfiltration to typosquatted domains, even for compromised packages that successfully executed.
Vendor security advisories / CVE monitoring Would Partially Help Advisory monitoring would have triggered rapid response, but only after public disclosure. Real-time runtime detection was the only pre-disclosure option.
Multi-factor authentication (MFA) on maintainer accounts Would Not Help The initial Trivy compromise exploited a misconfigured GitHub Actions workflow (pull_request_target), not a stolen password. MFA wouldn't have stopped this attack vector.

The Limits of SHA Pinning

The RoseSecurity blog (March 24) documented a specific vulnerability in GitHub's architecture that allowed the Trivy attack to bypass SHA pinning. GitHub makes fork commits reachable by SHA from the parent repository. An attacker who forks a repository and creates a malicious commit can produce a SHA that GitHub resolves as if it belonged to the original repository. The malicious commit swapped the checkout SHA while keeping the version comment (# v6.0.2) unchanged, relying on the fact that human reviewers read the comment rather than comparing 40-character hex strings.

The following table summarizes pinning strategies and their current limitations:

Pinning Strategy Limitation Guidance
Tag pinning Attackers can force-push any commit to any tag. Tags are mutable; they're not a reliable integrity mechanism. Don't use tags for security-sensitive actions or dependency references.
SHA pinning (commit hash) GitHub's fork-commit resolution allows attacker-controlled fork commits to be reachable by SHA from the parent repo. A malicious commit in a fork can produce a SHA that resolves from the official repo. After pinning a SHA, verify the commit exists on a release branch: gh api repos/{owner}/{repo}/commits/{sha}/branches-where-head; an empty response means the commit is orphaned and suspect.
SHA pinning + branch verification Adds one API call to the verification step. Best current practice for GitHub Actions pinning.
Mirroring critical actions into your own organization Requires ongoing maintenance to pull upstream updates. Eliminates fork-commit and upstream supply chain risks for critical workflows.

Prioritized Response Actions

1. Determine Exposure

Before rotating credentials, identify what was exposed. This determines the scope and urgency of everything else.

  • Audit CI/CD pipeline logs for the affected date ranges and package versions listed in the Attack Timeline above. Safe versions: Trivy v0.69.3, trivy-action v0.35.0, setup-trivy v0.2.6, LiteLLM 1.83.0, Telnyx 4.87.3+. Any earlier version in the affected range should be treated as compromised.
  • Search for the malware's exfiltration archive on build hosts and developer workstations: find / -name tpcp.tar.gz 2>/dev/null
  • Important: removing the affected packages does not remove the backdoor. Hosts that ran any compromised package may have sysmon.service installed and actively beaconing even after you've updated to clean versions. The persistence checks below are mandatory regardless of whether you've already remediated the packages.
  • Check for the backdoor service: systemctl status sysmon.service. Verify no file exists at ~/.config/sysmon/sysmon.py.
  • Check for CanisterWorm persistence: systemctl —user status pgmon.service. Look for ~/.local/share/pgmon/service.py.
  • If any build host ran inside a Kubernetes cluster, check for the DaemonSet-based backdoor: kubectl get daemonsets —all-namespaces and review for unexpected entries in kube-system. The malware creates privileged DaemonSets that survive container restarts.
  • Check Docker Hub for unexpected image tags without corresponding GitHub releases (0.69.5 and 0.69.6 for Trivy; any unrecognized tags for your own images).
  • Check GitHub accounts for unauthorized repositories named tpcp-docs or docs-tpcp.
  • For the full list of CanisterWorm-infected npm package names across the @emilgroup, @opengov, and @v7 namespaces, see the Mend.io CanisterWorm analysis. Check your dependency tree against that list.
  • Review network logs for outbound connections to C2 domains: scan.aquasecurtiy[.]org, checkmarx[.]zone, models.litellm[.]cloud, and the IP addresses listed in the Appendix. Also check for connections to *.trycloudflare.com from build environments.

Note:

If Step 1 confirms you ran a compromised package during the affected windows, proceed immediately with Steps 2 through 6. If you ran any of the packages but can’t confirm exposure, rotating credentials is still strongly recommended as a precaution.

2. Rotate ALL Credentials

Rotating everything simultaneously (atomically, meaning all at once with no old credentials still active) is the ideal approach, and you should do it if your tooling and team allow. When Aqua Security rotated credentials in stages, one missed service account gave TeamPCP everything they needed for the March 19 attack.

If simultaneous rotation isn't feasible, work through the tiers in the Credential Rotation Checklist in the Appendix in priority order, moving as fast as possible. The slower the rotation, the more critical verification becomes: every credential must be confirmed fully invalidated before you declare the rotation complete. Don't just issue new credentials; confirm the old ones are dead.

Treat this as an emergency change management process. Rotation will temporarily disrupt CI/CD pipelines and deployments; communicate the maintenance window to your development and DevOps teams, as well as customers, before starting. For most organizations, full rotation takes 1-3 business days.

Rotate all credentials as detailed in the Credential Rotation Checklist in the Appendix, working through the tiers in priority order and verifying each before declaring the rotation complete.

3. Audit and Re-image Affected Build Environments

The malware ran inside build pipelines and developer machines, not production. Audit accordingly:

  • Treat any self-hosted runner that processed a build during the affected window as potentially compromised; re-image it from a known-clean baseline rather than attempting to clean it.
  • If any host ran inside a Kubernetes cluster with a permissive service account, treat the entire cluster as potentially compromised. The Kubernetes lateral movement capability means a single infected container may have written the backdoor to every node.
  • Review GitHub Actions workflow files for unexpected changes to checkout SHAs or action references during March 2026.
  • Review access logs for all cloud services that received credentials from affected build environments.

4. Strengthen CI/CD Posture

These controls address the specific weaknesses this campaign exploited. Note: many applications have transitive dependencies (packages that are dependencies of your own dependencies). Audit your full dependency tree, not just your direct dependencies.

  • Fix the pull_request_target misconfiguration: Audit all GitHub Actions workflows for this trigger combined with checkout of the PR's code. This is the specific misconfiguration that enabled the initial Trivy breach. Restrict permissions to read-only at the workflow level by adding permissions: contents: read to workflows that don't need write access.
  • Use SHA pinning with branch verification: Pin GitHub Actions to full commit SHAs (not tags). After pinning, verify the commit isn't orphaned: gh api repos/{owner}/{repo}/commits/{sha}/branches-where-head; an empty response indicates an orphaned (potentially attacker-controlled) fork commit.
  • Enable artifact attestation: Use GitHub's built-in attestation feature (uses: actions/attest-build-provenance@v1) to verify build outputs were produced from known sources. This would have caught the Trivy tag/binary mismatch, and is now a CISA-recommended control for CI/CD environments.
  • Restrict outbound network access from build environments: Use allowlist-only egress in your build environment network policy. Build environments should only be able to reach known package registries and artifact stores, not arbitrary internet destinations. This is the single control most likely to have stopped the exfiltration even after execution.
  • Monitor for .pth file creation in Python environments: Alert on unexpected .pth files written to Python's site-packages directory. This technique was used in LiteLLM and was largely invisible to standard supply chain scanning tools.
  • Generate and maintain an SBOM (Software Bill of Materials): An SBOM lists every dependency and its version, enabling rapid exposure assessment when a new supply chain attack is disclosed. GitHub can generate SBOMs automatically via the dependency graph feature. Also enable Dependabot alerts and secret scanning; both are free for public and private repositories.
  • Consider mirroring critical GitHub Actions into your own organization: This eliminates upstream fork-commit and supply chain risks for workflows critical to your build process.

5. Block Arbitrary Outbound Access from Production and Build Environments

This is a durable architectural control that limits the blast radius of any supply chain attack, not just this one. It’s much easier to do when the infrastructure is nascent. If you’re a startup, do it now.

  • Production environments should have no ability to make arbitrary outbound connections. Use egress allowlists that permit only required API endpoints and internal services. A compromised dependency that executes in production shouldn't be able to beacon out to attacker infrastructure.
  • Build environments should similarly restrict outbound access to known registries (npm, PyPI, GitHub, your internal package mirror) and artifact storage. This is the control that would have stopped CanisterWorm's C2 beaconing and TeamPCP's exfiltration most reliably.
  • If full allowlisting isn't immediately feasible, implement network monitoring and alerting on outbound connections from build and production environments to newly-registered domains, unusual TLDs, or Cloudflare Tunnel URLs (*.trycloudflare.com), all of which were visible in this campaign.

6. Monitor for and Block Known Attacker Infrastructure

Block the following at your network perimeter and alert on any matching traffic from build environments:

  • C2 domains: scan.aquasecurtiy[.]org, checkmarx[.]zone, models.litellm[.]cloud, tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io
  • Known IP addresses: 23.142.184[.]129, 45.148.10[.]212, 63.251.162[.]11, 83.142.209[.]11, 83.142.209[.]203, 195.5.171[.]242, 209.34.235[.]18, 212.71.124[.]188
  • Alert on processes creating or modifying sysmon.service or pgmon.service on Linux build hosts and developer workstations.
  • Alert on GitHub API calls that create new public repositories from build or automation service accounts.
  • Alert on unexpected .pth files created in Python's site-packages directory.

We're Here to Help

For assistance implementing these recommendations or to discuss your specific risk profile, contact Exposure Security.

Appendix: References & IOCs

Regulatory References

  • CVE-2026-33634 (CVSS 9.4): CISA KEV: Trivy GitHub Actions workflow misconfiguration. Federal remediation deadline: April 8, 2026. Private organizations should treat this as a benchmark deadline.
  • GHSA-69fq-xp46-6x23: GitHub Security Advisory: pull_request_target with write permissions (initial Trivy access vector).
  • AD-2026-001 (TeamPCP): Singapore CSA: Covers the Trivy and Checkmarx KICS compromises.
  • AD-2026-002 (Concurrent axios attack): Singapore CSA: Covers a separate, concurrent supply chain attack on the axios npm package attributed to UNC1069 (a North Korean threat actor). Unrelated to TeamPCP but affects the same developer ecosystem. Check for axios versions 1.14.1 and 0.30.4 if relevant.

Credential Rotation Checklist (Prioritized Order)

Rotating everything simultaneously (atomically) is ideal: it eliminates the windows created when some old credentials remain active while others are already rotated. If simultaneous rotation isn't feasible, work through the tiers below in order, move as fast as possible, and triple-check each tier before moving to the next. Do not declare rotation complete until every old credential is confirmed fully invalidated.

Tier 1: Cloud Provider Credentials (Rotate First)

These carry the broadest access to production systems and data. Rotate these first regardless of what else is in your pipeline.

  • AWS IAM access keys and secret keys: rotate via IAM; deactivate old key IDs before or simultaneously with issuing new ones; confirm no active sessions using old key IDs in CloudTrail
  • GCP service account keys: rotate via IAM and Admin; revoke old key versions immediately after the new key is active
  • Azure client secrets and certificates: rotate in Entra ID under App Registrations; verify no remaining authorizations using old secret IDs in Azure activity logs

Tier 2: Code and Publishing Infrastructure (Rotate Second)

Compromise here enables further supply chain attacks against your own downstream users and customers.

  • GitHub personal access tokens (PATs) with admin or write scope
  • Consider migrating to fine-grained PATs with scoped repository access after rotation; classic PATs grant broad organization-wide permissions and are harder to audit.
  • GitHub organization-level secrets and Actions secrets (both repository and organization level)
  • npm publishing tokens: revoke via npmjs.com; check for any packages published during the exposure window
  • PyPI publishing tokens: revoke via pypi.org; check for any packages published during the exposure window
  • Docker Hub and container registry credentials
  • GPG signing keys used for commit or package signing: revoke and reissue; re-sign and republish any packages whose previous signatures used a compromised key; treat any commits signed during the exposure window as suspect until re-verified

Tier 3: Infrastructure Access

  • SSH keys stored in build environments or used by CI/CD workflows
  • Kubernetes service account tokens: rotate via kubectl; review RBAC permissions for all service accounts that had access during the exposure window and revoke any permissions that aren't strictly required
  • TLS private keys generated in or accessible from build environments

Tier 4: Application and SaaS API Keys

  • AI and LLM API keys: OPENAI_API_KEY, ANTHROPIC_API_KEY, and any other AI service credentials present in build environments
  • Database credentials and connection strings accessible from build environments
  • HashiCorp Vault tokens
  • SaaS platform tokens injected into CI/CD pipelines: Slack, Jira, PagerDuty, Salesforce, and any other services whose API keys are present as environment variables in build environments
  • VPN credentials
  • Cryptocurrency wallet keys, if present in any build environment

Tier 5: Verification (Not Optional)

Do not declare rotation complete until every item below is confirmed. Issuing new credentials without revoking old ones is not rotation; it is duplication.

  • For each rotated credential: confirm in your identity provider's audit logs that the old credential shows zero successful authentications after the rotation timestamp
  • Review AWS CloudTrail, GCP Cloud Audit Logs, Azure activity logs, and GitHub audit logs for unauthorized actions taken while old credentials were active. Rotation stops further access; the audit determines whether damage already occurred.
  • For npm and PyPI tokens: verify no unexpected packages were published under your account or organization during the exposure window
  • For GPG keys: confirm all dependent package repositories have been updated to trust the new key and that the old key is published as revoked

Indicators of Compromise (IOCs)

Command & Control ("C2") Domains

  • scan.aquasecurtiy[.]org: Trivy primary C2 (typosquat of aquasecurity.org)
  • checkmarx[.]zone: Checkmarx KICS; also used by backdoor for 50-minute polling
  • models.litellm[.]cloud: LiteLLM
  • tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io: ICP decentralized backup C2; can't be taken down conventionally

IP Addresses

  • 23.142.184[.]129
  • 45.148.10[.]212
  • 63.251.162[.]11
  • 83.142.209[.]11
  • 83.142.209[.]203
  • 195.5.171[.]242
  • 209.34.235[.]18
  • 212.71.124[.]188

Cloudflare Tunnel URLs

  • championships-peoples-point-cassette.trycloudflare[.]com
  • create-sensitivity-grad-sequence.trycloudflare[.]com
  • investigation-launches-hearings-copying.trycloudflare[.]com
  • plug-tab-protective-relay.trycloudflare[.]com
  • souls-entire-defined-routes.trycloudflare[.]com

Persistence Artifacts (Linux)

  • ~/.config/sysmon/sysmon.py: backdoor script (systemd service sysmon.service, described as "System Telemetry Service")
  • ~/.local/share/pgmon/service.py: CanisterWorm backdoor (systemd service pgmon, disguised as PostgreSQL monitoring tool)
  • /tmp/pglog: payload staging; /tmp/.pg_state: last executed payload URL
  • tpcp.tar.gz: exfiltration archive
  • litellm_init.pth: LiteLLM .pth trigger in Python site-packages
  • hangup.wav (Windows) / ringtone.wav (Linux): Telnyx WAV steganography files
  • tpcp-docs or docs-tpcp: GitHub repo created in victim's org using stolen GITHUB_TOKEN

Malware Script Filenames

  • kamikaze.sh: primary Trivy payload (evolved through 3 versions)
  • kube.py: second-stage modular payload
  • prop.py: propagation component
  • proxy_server.py: proxy component
  • deploy.js: CanisterWorm self-propagation
  • index.js: CanisterWorm postinstall entry point
  • setup.sh: subverted Checkmarx container entrypoint

Affected Package Versions

  • Trivy binary: v0.69.4 and malicious Docker Hub tags 0.69.5 and 0.69.6 (no corresponding GitHub releases)
  • Trivy GitHub Actions: aquasecurity/trivy-action (76 of 77 version tags force-pushed), aquasecurity/setup-trivy (all tags force-pushed)
  • Checkmarx: checkmarx/kics-github-action (all 35 version tags), checkmarx/ast-github-action version 2.3.28
  • LiteLLM: versions 1.82.7 and 1.82.8 on PyPI (version 1.83.0 is clean)
  • Telnyx Python SDK: versions 4.87.1 and 4.87.2 on PyPI
  • CanisterWorm-infected npm packages: 47+ packages across @emilgroup, @opengov, and @v7 namespaces

SHA256 Hashes for Known Malicious Files

  • 0880819ef821cff918960a39c1c1aada55a5593c61c608ea9215da858a86e349
  • 0c6a3555c4eb49f240d7e0e3edbfbb3c900f123033b4f6e99ac3724b9b76278f
  • 18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a
  • 5e2ba7c4c53fa6e0cef58011acdd50682cf83fb7b989712d2fcf1b5173bad956
  • 61ff00a81b19624adaad425b9129ba2f312f4ab76fb5ddc2c628a5037d31a4ba
  • 822dd269ec10459572dfaaefe163dae693c344249a0161953f0d5cdd110bd2a0
  • 887e1f5b5b50162a60bd03b66269e0ae545d0aef0583c1c5b00972152ad7e073
  • bef7e2c5a92c4fa4af17791efc1e46311c0f304796f1172fce192f5efc40f5d7
  • cd08115806662469bbedec4b03f8427b97c8a4b3bc1442dc18b72b4e19395fe3
  • Full hash list: Unit 42 TeamPCP Threat Brief

SHA256 Hashes for Self-Signed Certificates

These certificates are used for TLS on attacker C2 infrastructure. Check network security tooling and TLS inspection logs for connections to hosts presenting these certificate fingerprints.

  • 30015DD1E2CF4DBD49FFF9DDEF2AD4622DA2E60E5C0B6228595325532E948F14
  • 41C4F2F37C0B257D1E20FE167F2098DA9D2E0A939B09ED3F63BC4FE010F8365C
  • D8CAF4581C9F0000C7568D78FB7D2E595AB36134E2346297D78615942CBBD727

References

  • Root cause analysis of the initial Trivy breach, including the incomplete credential rotation that allowed the attacker to retain access via the Argon-DevOps-Mgt bot account.
  • Detailed technical breakdown of the Trivy-to-LiteLLM attack chain, the .pth file technique, CanisterWorm stages, and malware payload structure.
  • Comprehensive campaign analysis including threat actor history, CanisterWorm ICP C2 and wiper, Telnyx WAV steganography, complete IOCs, and SHA256 hashes.
  • Attribution of Trivy and Checkmarx compromises to TeamPCP; shared C2 infrastructure analysis.

Wiz: TeamPCP and LAPSUS$ Credential Monetization (March 30)

  • Confirmation of TeamPCP's partnership with the LAPSUS$ extortion group and credential monetization strategy.
  • Technical analysis of how the Trivy attack bypassed SHA pinning via GitHub's fork commit reachability; documents the checkout SHA swap with unchanged version comment.
  • First confirmed victim disclosure: 4TB exfiltration breakdown and Tailscale VPN credential as initial access vector.
  • Deep dive into CanisterWorm's ICP C2 architecture, four-stage attack, and self-propagation mechanics.
  • Captured malware samples for security researchers: orchestrator, harvester, and backdoor components.
This briefing is part of Exposure Security's ongoing executive intelligence series. For questions about how this applies to your organization specifically, contact us.
← All Briefings