UPDATE - March 26, 2026: This article covers the LiteLLM compromise (Day 6 of the TeamPCP campaign). For the initial Trivy supply chain attack, see the separate analysis at https://zerotolerance.me/cyberthreats/trivy-supply-chain-cve-2026-33634.html
On March 24, 2026, TeamPCP backdoored LiteLLM - the leading open-source AI model proxy framework with 480 million total PyPI downloads and presence in 36% of cloud environments - by publishing malicious versions 1.82.7 and 1.82.8 to PyPI. The compromise used PyPI credentials stolen from LiteLLM co-founder Krish Dholakia's GitHub account, which was itself compromised through credentials harvested during the Trivy GitHub Actions attack six days earlier.
The malicious packages harvested environment variables, SSH keys, cloud credentials across AWS, GCP, and Azure, Kubernetes configurations, and cryptocurrency wallets, exfiltrating everything via AES-256/RSA-4096 encryption.
Version 1.82.8 introduced a .pth file persistence mechanism that executes a double base64-encoded payload on every Python process on the infected system - not just when importing LiteLLM. PyPI quarantined both versions within approximately 3-5 hours.
Mandiant CTO Charles Carmakal disclosed at RSA Conference 2026 that the broader TeamPCP campaign has compromised 1,000+ SaaS environments, with projections reaching 10,000+.
This is the most significant software supply chain attack of 2026 - six days, five ecosystems, and hundreds of gigabytes of stolen credentials.
KEY FACTS
- .What: TeamPCP backdoored LiteLLM AI proxy framework on PyPI with credential-stealing malware and persistent system-level backdoors - the sixth stage of a campaign spanning five package ecosystems.
- .Who: LiteLLM (480M total PyPI downloads, 95M monthly, 36% cloud environment presence). Downstream: AI/ML teams, SaaS platforms, LLM orchestration pipelines globally.
- .How: PyPI credentials stolen via credential chaining from the Trivy GitHub Actions compromise (
CVE-2026-33634). LiteLLM co-founder's GitHub account compromised through harvested Trivy CI/CD secrets. - .Data: Environment variables, SSH keys, AWS/GCP/Azure credentials, Kubernetes configs, Docker configs, shell history, database credentials, CI/CD secrets, cryptocurrency wallets.
- .Actor: TeamPCP (DeadCatx3, PCPcat, PersyPCP, ShellForce) - hybrid cybercrime group, first observed November 2025.
- .Impact: 1,000+ compromised SaaS environments (Mandiant, confirmed at RSA 2026). Projected 10,000+. Attacker claims "hundreds of gigabytes of data and more than half a million accounts."
FULL CAMPAIGN TIMELINE
The LiteLLM compromise is Day 6 of the TeamPCP campaign - the broadest software supply chain attack documented in 2026. The full timeline:
Day 0 - February 2026 (GitHub): TeamPCP exploited a pull_request_target workflow misconfiguration in Aqua Security's Trivy repository. The vulnerable trigger processed untrusted code from external pull requests while granting access to repository secrets.
TeamPCP submitted a crafted PR that extracted a Personal Access Token (PAT) with write access to Trivy's GitHub Actions, Docker images, and package registries.
Day 1 - March 19 (GitHub Actions + Docker): TeamPCP used the stolen PAT to force-push 76 of 77 version tags in trivy-action and 7 tags in setup-trivy to credential-stealing payloads.
Malicious Trivy binaries (v0.69.4-v0.69.6) were published to GitHub Releases, Docker Hub, GitHub Container Registry, and Amazon ECR. Every CI/CD pipeline that pulled :latest or a tagged version of Trivy received the compromised binary.
CVE-2026-33634 was assigned (CVSS v4: 9.4, NVD v3.1: 8.8, CWE-506).
Day 2 - March 20 (npm): Stolen npm tokens harvested from the Trivy compromise fed CanisterWorm - a self-propagating npm worm that used ICP blockchain canisters for command-and-control (the first documented use of decentralized blockchain C2 in a supply chain attack).
Initial infection: 47+ packages. Final scope: 141 artifacts across 66+ packages.
Day 4 - March 22 (Docker + GitHub): Malicious Docker images pushed to registries.
The Argon-DevOps-Mgt account defaced 44 Aqua Security internal repositories in a scripted 2-minute burst, exposing proprietary source code for Tracee, internal Trivy forks, CI/CD pipeline configurations, and Kubernetes operator code.
Day 5 - March 23 (GitHub Actions + Open VSX): Checkmarx kics-github-action v1.1 and ast-github-action v2.3.28 compromised. OpenVSX extensions ast-results 2.53.0 (~36,000 downloads) and cx-dev-assist 1.7.0 (~500 installations) poisoned.
The checkmarx[.]zone domain served as both exfiltration endpoint and C2 polling server.
Independent verification confirms that checkmarx[.]zone has zero Certificate Transparency log entries - no TLS certificate was ever issued for this domain through any publicly-logged certificate authority.
This means the domain either operated over unencrypted HTTP, used a self-signed certificate, or employed a non-logging CA - a notable OPSEC divergence from the other C2 domains in this campaign, which used Let's Encrypt certificates that left CT footprints.
Day 6 - March 24 (PyPI): LiteLLM v1.82.7 and v1.82.8 published to PyPI using credentials stolen from LiteLLM co-founder Krish Dholakia's compromised GitHub account. PyPI quarantined both versions within 3-5 hours. This is the attack covered in this article.
Total scope: 5 ecosystems (GitHub Actions, Docker Hub, npm, Open VSX, PyPI). 20,000+ repositories potentially vulnerable. 1,000+ confirmed compromised SaaS environments (Mandiant).
WHAT HAPPENED - LITELLM
At approximately 08:30 UTC on March 24, 2026, TeamPCP published LiteLLM version 1.82.7 to PyPI. The package contained a malicious payload injected into litellm/proxy/proxy_server.py as base64-encoded content.
proxy_server was imported - standard operations for anyone using LiteLLM as an AI model proxy. Within hours, version 1.82.8 followed with an escalated attack: it included a litellm_init.pth file alongside the modified proxy_server.py.
The .pth mechanism represents a significant escalation in persistence technique. Per Python's site module documentation, executable lines in .pth files run during interpreter startup.
The litellm_init.pth file executed a double base64-encoded payload via subprocess whenever any Python process launched on the system - not just when importing LiteLLM. This means a data scientist running an unrelated Jupyter notebook, a DevOps engineer executing an Ansible playbook, or a developer running pytest would all trigger the malicious payload.
The payload's capabilities were comprehensive.
Upon execution, it harvested environment variables (which in cloud environments typically contain API keys, database connection strings, and service account tokens), SSH private keys, cloud provider credentials for AWS, GCP, and Azure, Kubernetes configuration files, Docker configuration files, shell command history, database credentials, CI/CD pipeline secrets, and cryptocurrency wallet files.
The harvested data was encrypted locally using AES-256 session keys wrapped with RSA-4096 public keys - ensuring only the attacker could decrypt the exfiltrated material - and transmitted to models.litellm[.]cloud with the HTTP header X-Filename: tpcp.tar.gz.
The encryption-before-exfiltration approach defeats most DLP solutions that rely on pattern matching unencrypted content.
The malware installed persistence beyond the .pth file. It deployed a Python script at ~/.config/sysmon/sysmon.py and registered a systemd unit at ~/.config/systemd/user/sysmon.service, ensuring the backdoor survived package removal or updates.
It polled https://checkmarx[.]zone/raw for follow-on payloads - the same domain used in the Checkmarx GitHub Actions compromise on Day 5. When Kubernetes service account tokens were available in the environment, the payload created privileged pods matching the pattern node-setup-* with two container variants: kamikaze (destructive operations) and provisioner (standard backdoor).
This Kubernetes lateral movement capability means a single compromised developer laptop with kubectl access could lead to full cluster takeover.
PyPI's security team quarantined both versions between approximately 11:25 and 16:00 UTC on March 24 - an exposure window of roughly 3-5 hours. Given LiteLLM's 95 million monthly download rate, even a brief exposure window is significant.
LiteLLM removed the compromised packages, rotated all maintainer credentials, engaged Google's Mandiant for forensic analysis, paused all new releases pending a supply chain security review, and published a security advisory at docs.litellm.ai/blog/security-update-march-2026 recommending that all users rotate secrets, inspect systems for litellm_init.pth, and pin to version 1.82.6.
THREAT ACTOR
TeamPCP - also tracked as DeadCatx3, PCPcat, PersyPCP, and ShellForce - is a hybrid cybercrime group first observed in November 2025, with a Telegram channel (700+ members) dating to July 30, 2025. The group's December 2025 campaign compromised 60,000+ cloud servers (97% on Azure and AWS) by targeting exposed Docker APIs, Kubernetes clusters, Redis servers, and React/Next.js applications vulnerable to CVE-2025-55182 (React2Shell, CVSS 10.0).
That campaign used the open-source Sliver C2 framework and established TeamPCP as a credible threat to cloud infrastructure.
The Trivy-to-LiteLLM campaign demonstrates a credential-chaining technique that is the defining characteristic of this actor's operational model. Rather than attacking each target independently, TeamPCP uses access gained from one compromise to pivot into the next.
A single pull_request_target misconfiguration in Trivy yielded a PAT that unlocked GitHub Actions, which yielded npm tokens that fed CanisterWorm, which yielded PyPI credentials that compromised LiteLLM. Each ecosystem breach was not a separate attack - it was the next link in a chain that began with one vulnerable CI/CD configuration.
The group's motivation is assessed as hybrid: financial gain (credential theft, cryptocurrency wallet theft), data theft at scale (environment variables, cloud credentials), attention-seeking (defacement of 44 Aqua Security repos, taunting messages), and a geopolitical dimension.
Researchers documented an Iran-targeted Kubernetes wiper component in the broader campaign that selectively destroys cluster infrastructure for systems identified as Iranian - an unusual ideological element for an otherwise financially-motivated actor.
TeamPCP's operational sophistication is notable.
The use of ICP blockchain canisters for C2 (first documented in a supply chain attack), double base64-encoded payloads, AES-256/RSA-4096 encryption of exfiltrated data, .pth file persistence targeting Python's interpreter startup, and the systematic progression across five ecosystems in six days indicate a well-resourced and operationally mature group despite its relatively recent emergence.
Independent verification confirms that the ICP C2 canister (tdtqy-oyaaa-aaaae-af2dq-cai) remains active and is still being updated as of March 27, 2026 - despite public identification as attack infrastructure, DFINITY governance has not frozen or removed it, underscoring the resilience of decentralized C2 channels.
WHAT WAS EXPOSED
The LiteLLM backdoor targeted the highest-value credentials in any cloud-native environment:
- .Cloud provider credentials - AWS access keys, GCP service account JSON files, Azure connection strings. These provide direct access to cloud infrastructure, storage buckets, databases, and compute resources.
- .Kubernetes configuration files - kubeconfig files containing cluster endpoints, certificates, and authentication tokens. With these, an attacker can deploy workloads, exfiltrate data from pods, and pivot across namespaces.
- .AI/ML API keys - LiteLLM's primary function is proxying requests to LLM providers (OpenAI, Anthropic, Google, Azure OpenAI). Environment variables on LiteLLM instances typically contain API keys for these services, representing both financial exposure (API billing) and data exposure (prompt/response logs).
- .SSH private keys - enabling direct server access without credential rotation.
- .CI/CD secrets - pipeline tokens, registry credentials, deployment keys. These enable the same credential-chaining technique TeamPCP used to pivot from Trivy to LiteLLM.
- .Database credentials - connection strings for PostgreSQL, MySQL, MongoDB, Redis, and other datastores commonly configured via environment variables.
- .Cryptocurrency wallets - wallet files enabling direct financial theft.
- .Shell history - containing commands, connection strings, and credentials typed at the command line.
- .Docker configuration files - including registry authentication tokens.
The attacker claims "hundreds of gigabytes of data and more than half a million accounts" stolen across the entire campaign.
This claim is unconfirmed but consistent with the scale of the operation: LiteLLM's presence in 36% of cloud environments means the credential-harvesting payload had access to a significant fraction of cloud infrastructure globally.
TECHNICAL FAILURE CHAIN
1. Credential Chaining from Trivy to LiteLLM. The root cause of the LiteLLM compromise was not a vulnerability in LiteLLM itself - it was the propagation of stolen credentials from the Trivy GitHub Actions attack.
LiteLLM co-founder Krish Dholakia's GitHub account was compromised through credentials harvested during the Trivy CI/CD compromise. Those GitHub credentials provided access to PyPI publishing tokens.
No second factor blocked the attacker's use of stolen PyPI credentials to publish malicious packages.
2. No PyPI Two-Factor Enforcement on Publishing. PyPI supports two-factor authentication and trusted publishers (OIDC-based, keyless publishing from CI/CD). The compromised account did not require a second factor or hardware key to publish new package versions.
A FIDO2 hardware key requirement on the PyPI maintainer account would have stopped this attack entirely.
3. No Code Signing or Provenance Verification. PyPI packages were not signed. No SLSA provenance attestation was attached to LiteLLM releases. Consumers had no mechanism to verify that v1.82.7 was published by the legitimate maintainer versus an attacker with stolen credentials.
4. .pth File Persistence Mechanism. Python's .pth file mechanism - designed for legitimate path configuration - executes arbitrary code during interpreter startup.
This is a known persistence vector, yet no widely-deployed security tool flags .pth files with executable content in package installations by default. The v1.82.8 .pth payload ran on every Python process, vastly expanding the blast radius beyond LiteLLM users.
5. No Egress Filtering or DLP on Credential Stores. The payload exfiltrated data to models.litellm[.]cloud - a domain that had no prior reputation and was registered specifically for this campaign.
Passive infrastructure analysis reveals the TLS certificate for models.litellm[.]cloud was issued via Let's Encrypt on March 23 - one day before the LiteLLM attack launched on March 24 - confirming the compromise was pre-planned infrastructure staging, not opportunistic.
Organizations without DNS-layer filtering, egress proxy inspection, or anomaly detection on outbound connections had no mechanism to detect the exfiltration. The AES-256/RSA-4096 encryption of the exfiltrated payload defeated content-based DLP.
6. Secrets Stored in Environment Variables Without Rotation. The payload harvested credentials from environment variables - the default configuration method for most cloud-native applications.
Static credentials in environment variables, rather than short-lived tokens from a secrets manager with automatic rotation, gave the attacker persistent access even after the malicious package was removed.
7. Kubernetes Service Account Overprivilege. The payload created privileged pods when Kubernetes tokens were available.
This is only possible when the compromised service account has permissions to create pods - a violation of least-privilege that is endemic in Kubernetes environments. Default service account tokens mounted into pods provided the lateral movement path.
INDICATORS OF COMPROMISE
CVE IDs:
- .
CVE-2026-33634- CVSS v4: 9.4, NVD v3.1: 8.8, CWE-506
Malicious Domains:
- .models.litellm[.]cloud - Primary exfiltration endpoint
- .checkmarx[.]zone - C2 polling server
Blockchain C2:
- .ICP Canister ID: tdtqy-oyaaa-aaaae-af2dq-cai (CanisterWorm, still active)
Compromised Packages:
- .litellm v1.82.7 - Malicious payload in proxy_server.py
- .litellm v1.82.8 - Escalated with .pth persistence
- .Safe version: litellm v1.82.6
Persistence Artifacts:
- .litellm_init.pth - Executes on every Python process startup
- .~/.config/sysmon/sysmon.py - Persistent backdoor
- .~/.config/systemd/user/sysmon.service - Systemd persistence masquerading as "System Telemetry Service"
Exfiltration:
- .HTTP header X-Filename: tpcp.tar.gz
- .AES-256/RSA-4096 hybrid encryption
- .Targets: AWS/GCP/Azure credentials, SSH keys, Kubernetes configs, crypto wallets
Threat Actor Aliases:
- .TeamPCP / DeadCatx3 / PCPcat / PersyPCP / ShellForce
MITRE ATT&CK:
- .T1195.002 - Supply Chain Compromise
- .T1547.015 - .pth File Persistence
- .T1543.002 - Systemd Service
- .T1567.002 - Exfiltration Over Web Service
- .T1610 - Deploy Container (Kubernetes)
REGULATORY EXPOSURE
Software supply chain attacks targeting open-source AI infrastructure create a unique regulatory challenge: the compromised component is not sold by a vendor with a direct contractual relationship to downstream users.
Liability flows through a chain of open-source dependencies, cloud service configurations, and organizational security practices.
- .NIST SSDF (SP 800-218) / EO 14028 - Federal agencies and their contractors are required to attest to secure software development practices, including dependency integrity verification. Organizations that pulled LiteLLM without provenance verification may face compliance gaps under federal software supply chain requirements.
- .CISA Secure by Design - CISA's guidance explicitly calls for software publishers to implement provenance attestation and dependency pinning. The absence of SLSA provenance on LiteLLM packages enabled undetected substitution.
- .SEC 8-K Disclosure (Item 1.05) - Public companies that used the compromised LiteLLM versions and experienced credential theft may face material cybersecurity incident disclosure obligations within 4 business days of materiality determination.
- .CCPA/CPRA - If compromised cloud credentials led to downstream access to California residents' personal information, notification requirements and penalties of $7,500 per intentional violation apply. AI companies processing consumer data through LiteLLM proxies are directly exposed.
- .HIPAA - Healthcare organizations using LiteLLM to proxy AI model requests that include or are adjacent to protected health information face Security Rule violations. The credential theft could enable unauthorized access to PHI stored in cloud infrastructure. Fines up to $2.1M per violation category per year.
- .GDPR (Articles 5, 32, 33, 34) - EU-based organizations using compromised versions face Article 32 scrutiny on the "appropriateness" of security measures - specifically, the absence of dependency verification, code signing, and egress monitoring. 72-hour notification to DPAs is required under Article 33. Fines up to EUR 20M or 4% annual global turnover.
- .UK GDPR / DPA 2018 - Same analysis for UK organizations. ICO enforcement; fines up to GBP 17.5M or 4% turnover.
- .Saudi PDPL - Saudi organizations using LiteLLM in AI/ML infrastructure face fines up to SAR 5M. NCA Essential Cybersecurity Controls mandate supply chain risk management for government and critical infrastructure entities.
- .UAE PDPL (Federal Decree-Law No. 45/2021) - UAE organizations face fines up to AED 10M. TDRA incident reporting obligations apply.
- .EU AI Act - Organizations using LiteLLM as part of high-risk AI systems face additional obligations under the EU AI Act regarding supply chain integrity of AI components. The compromise of an AI orchestration layer directly implicates AI-specific regulatory requirements.
- .EU Cyber Resilience Act (CRA) - When fully effective, the CRA will impose security requirements on software with digital elements, including open-source stewards. The LiteLLM incident is exactly the class of supply chain compromise the CRA was designed to address.
INTELLIGENCE GAPS
The following gaps exist in the public record for this incident:
1. The exact number of organizations that installed LiteLLM v1.82.7 or v1.82.8 during the 3-5 hour exposure window has not been disclosed by PyPI, LiteLLM, or Mandiant.
Independent verification confirms both versions have been completely removed from PyPI (not merely yanked) and are preserved only on PyPI Inspector for security research.
2. TeamPCP's claim of "hundreds of gigabytes of data and more than half a million accounts" stolen across the broader campaign is unverified and originates solely from the threat actor.
3. Whether the .pth persistence mechanism in v1.82.8 was deployed on systems where the malicious proxy_server.py in v1.82.7 was not triggered (e.g., systems that installed LiteLLM but did not run the proxy) has not been assessed in public reporting.
4. The credential chain from Trivy to LiteLLM co-founder Krish Dholakia's GitHub account has been described at a high level, but the specific mechanism by which Trivy CI/CD secrets yielded PyPI publishing access has not been detailed in a published forensic report.
Independent verification confirms that new maintainer accounts (@krrish-berri-2 and @ishaan-berri) were created as part of credential rotation, consistent with the original accounts being fully compromised.
5. Whether any of the Kubernetes wiper payloads (kamikaze containers targeting Iranian systems) were successfully deployed through LiteLLM-compromised environments, as opposed to earlier stages of the campaign, has not been confirmed.
6. The ICP blockchain C2 canister used by CanisterWorm (tdtqy-oyaaa-aaaae-af2dq-cai) remains active and has not been frozen by DFINITY governance as of March 27, 2026. Whether DFINITY has been formally notified and what governance process exists for freezing malicious canisters remains unclear.
UPDATE - March 27, 2026: Independent passive OSINT verification by ZERO|TOLERANCE has confirmed all primary claims in this article.
The CVSS v3.1 score in the campaign timeline has been corrected from the vendor-assessed 9.9 to the NVD-assessed 8.8. Certificate Transparency analysis confirmed the models.litellm[.]cloud exfiltration domain was staged one day before the attack.
Full verification methodology and findings are documented separately.
ZERO|TOLERANCE Advisory
This was not a vulnerability in LiteLLM. It was the sixth link in a credential chain that began with a misconfigured pull_request_target workflow in Aqua Security's Trivy repository - one stolen PAT cascaded through GitHub Actions, npm, and a self-propagating worm before yielding PyPI publishing credentials for a package installed in 36% of cloud environments.
Six days, five ecosystems. At every link, a single control would have broken the chain. None was in place.
FIDO2 hardware keys on all package registry accounts would have ended this attack at the publishing step.
TeamPCP used PyPI credentials stolen from LiteLLM co-founder Krish Dholakia's compromised GitHub account to publish versions 1.82.7 and 1.82.8 - the account did not require a second factor.
A FIDO2 key is physically bound to the possessor and cryptographically bound to the origin domain through a challenge-response mechanism that cannot be phished, replayed, or used remotely.
PyPI also supports trusted publishers - an OIDC-based, keyless publishing mechanism tied to specific GitHub Actions workflows that eliminates long-lived credentials entirely. With trusted publishers, there are no credentials to steal.
SLSA provenance attestation gives downstream consumers the mechanism to detect exactly this kind of substitution. Versions 1.82.7 and 1.82.8 were not produced by LiteLLM's legitimate CI/CD pipeline - they were uploaded directly by an attacker from a non-CI environment.
A SLSA Level 3 attestation links each artifact to a specific source commit, build system, and builder identity, cryptographically signed and independently verifiable.
Any consumer checking provenance would have seen that the new versions carried no valid attestation and rejected the package automatically. The credential was real. The package was not.
Organizations consuming open-source packages should pin to cryptographic hashes, not version numbers - version tags point to whatever artifact currently occupies that slot, and that artifact changed when TeamPCP published.
Any pipeline pinned to the known-good hash of v1.82.6 would have failed immediately when PyPI served a different hash, turning a supply chain compromise into a visible build failure.
For credentials already harvested, the defense is short-lived tokens: HashiCorp Vault with dynamic secrets, AWS STS for temporary credentials, or GCP workload identity federation with sub-hour rotation limits the attacker's window to minutes.
The difference between static AWS access keys and 15-minute STS tokens is the difference between persistent cloud access and a credential that expired before the attacker used it.
The .pth file persistence mechanism in version 1.82.8 transformed this from a LiteLLM-specific compromise into a system-wide backdoor.
Python's .pth mechanism executes arbitrary code during interpreter startup - the litellm_init.pth file ran a double base64-encoded payload on every Python process: Jupyter notebooks, Ansible playbooks, pytest runs, Django commands.
Security teams should audit all .pth files in site-packages immediately - legitimate .pth files contain directory paths only, while malicious ones contain import statements or exec() calls. EDR solutions should flag .pth creation with executable content as a high-severity event.
When the payload detected Kubernetes service account tokens, it created privileged pods (node-setup-*) for destructive operations and persistent backdoor access.
Setting automountServiceAccountToken: false on pods that do not require API access, restricting pod creation to dedicated deployment service accounts with namespace-scoped RBAC, and enforcing OPA Gatekeeper policies that reject privileged pod creation from non-CI accounts would have blocked this lateral movement entirely.
The distance between "compromised Python environment" and "full cluster takeover" should require multiple authorization boundaries - in most Kubernetes deployments, that distance is zero.
SOURCES
Datadog Security Labs, Wiz, ReversingLabs, The Hacker News, Kaspersky, Snyk, LiteLLM Official Blog (docs.litellm.ai/blog/security-update-march-2026), Palo Alto Networks, The Register, Endor Labs, Help Net Security, Mandiant, Microsoft Security Blog, Aqua Security, CrowdStrike, Socket.dev, StepSecurity, Aikido Security, ZERO|TOLERANCE Independent OSINT Verification (March 27, 2026)