The software supply chain is experiencing a cascading failure. The threat actor known as TeamPCP—the group responsible for the recent, devastating compromises of Trivy and KICS—has successfully pivoted their attacks into the Python ecosystem.
On March 24, 2026, multiple security vendors, including Endor Labs and JFrog, confirmed that the highly popular AI gateway package litellm was compromised on the Python Package Index (PyPI). Malicious versions 1.82.7 and 1.82.8 were published directly to PyPI, bypassing the official GitHub release pipeline.
The cause? It is highly probable that the maintainer’s PyPI credentials were stolen during the recent Trivy CI/CD compromise. As Wiz’s Head of Threat Exposure, Gal Nagli, stated: “Trivy gets compromised → LiteLLM gets compromised → credentials from tens of thousands of environments end up in attacker hands → and those credentials lead to the next compromise. We are stuck in a loop.”
Here is a technical breakdown of how the LiteLLM malware operates, its severe impact on Kubernetes clusters, and the immediate steps you must take to secure your environment.
What to Remember
- Compromised Versions: LiteLLM versions 1.82.7 and 1.82.8 were injected with sophisticated credential-harvesting malware on PyPI.
- “Zero-Click” Threat: Version 1.82.8 utilized a
.pthfile (litellm_init.pth) to execute payloads automatically upon starting the Python interpreter, requiring no explicit import by the developer. - Extensive Exfiltration: The malware targets environment variables, SSH keys, cloud provider secrets (AWS, GCP, Azure), Kubernetes tokens, and crypto wallets.
- Kubernetes Lateral Movement: If executed within a cluster, the payload enumerates nodes and deploys highly privileged pods to establish persistence (
sysmon.py) across the entire infrastructure. - Assume Breach: If these versions were pulled into your environment, you must immediately rotate all exposed credentials and hunt for persistence artifacts.
The Anatomy of the LiteLLM Backdoor
TeamPCP deployed a sophisticated, multi-stage payload designed for maximum credential extraction, stealth, and persistence. The attack escalated in severity between the two malicious releases.
Version 1.82.7: The Import Trigger
In the first compromised version, the malicious code was embedded directly within litellm/proxy/proxy_server.py.
- The Trigger: The payload executed only when a developer or application actively ran
import litellm.proxy. - The Action: It initiated the credential harvesting sequence (detailed below).
Version 1.82.8: The “Zero-Click” .pth Execution
Just hours later, the attackers uploaded v1.82.8, introducing a much more aggressive vector: a malicious .pth file (litellm_init.pth) placed in the root of the wheel package.
- The Trigger: Python
.pthfiles placed in thesite-packagesdirectory are processed automatically bysite.pyevery time the Python interpreter starts. - The Impact: Simply installing the package was enough. Any subsequent execution of Python on that machine—even a script completely unrelated to
litellm—triggered the malware. - The Execution: The file contained a single line that spawned a detached child process (
subprocess.Popen) to execute a double Base64-encoded payload in the background, making it invisible to developers.
The Three-Stage Payload
Once triggered, the malware decodes an orchestrator that executes three distinct phases:
Stage 1: The Ultimate Credential Harvester
The script aggressively sweeps the host machine for secrets:
- Environment Variables: Dumps all
printenvdata (capturing API keys and cloud tokens). - SSH & Git: Steals
id_rsa,id_ed25519,known_hosts, and.git-credentials. - Cloud Secrets: Harvests
~/.aws/credentials,application_default_credentials.json(GCP), and Azure configs. - Kubernetes: Steals
~/.kube/configand service account tokens. - Wallets & Databases: Targets crypto wallet directories (Bitcoin, Ethereum, Solana) and database configs (
.pgpass,.my.cnf).
Stage 2: Encryption & Exfiltration
To evade Data Loss Prevention (DLP) tools, the stolen data is highly encrypted:
- Step 1: It generates a random 32-byte AES-256 session key.
- Step 2: It encrypts the data using AES-256-CBC.
- Step 3: It encrypts the AES key using a hardcoded RSA-4096 public key.
- Step 4: It packages everything into an archive named
tpcp.tar.gz. - Step 5: It exfiltrates the archive via an HTTPS POST request to an attacker-controlled, typosquatted domain:
https://models.litellm[.]cloud(Note: the official domain is.ai).
Stage 3: Kubernetes Lateral Movement & Persistence
If the malware detects it is running inside a Kubernetes cluster (by finding a service account token), it attempts to pivot from a single pod to the entire infrastructure:
- Step 1: It enumerates all nodes in the cluster.
- Step 2: It deploys a highly privileged pod to every node.
- Step 3: These pods
chrootinto the host file system. - Step 4: They install a persistence dropper (
sysmon.py) as asystemduser service (sysmon.service) on every node. - Step 5: This persistent backdoor polls
checkmarx[.]zone/rawevery 50 minutes to fetch and execute next-stage payloads.
Immediate Remediation and Detection
The LiteLLM maintainers have since deleted the compromised packages, rotated all accounts, and engaged Mandiant for incident response. However, if your systems pulled these packages on March 24, 2026, you must assume total compromise.
Action Plan:
- Audit Installs: Check all local machines, CI/CD pipelines, and Docker images to see if
litellm==1.82.7or1.82.8was installed.- Quick Check: Look for the presence of
litellm_init.pthin your Pythonsite-packages/directory.
- Quick Check: Look for the presence of
- Rotate EVERYTHING: If the package was installed, you must immediately revoke and rotate all credentials that were present on that machine. This includes cloud IAM keys, SSH keys, database passwords, and personal access tokens (PATs).
- Hunt for Persistence (K8s):
- Check for rogue or unrecognized privileged pods running across your Kubernetes nodes.
- Inspect host nodes for the
~/.config/sysmon/sysmon.pyfile or thesysmon.servicesystemd unit.
- Review Network Logs: Query your SIEM or firewalls for egress traffic to:
models.litellm[.]cloudcheckmarx[.]zone
Conclusion
TeamPCP has made their intentions clear. In a message on their Telegram channel, they mocked the security industry: “The snowball effect from this will be massive… many of your favourite security tools and open-source projects will be targeted in the months to come so stay tuned.”
The pivot from compromising CI/CD tools (Trivy) to poisoning production runtime packages (LiteLLM) demonstrates a deliberate, highly effective escalation strategy. Pinning dependencies to exact versions is no longer enough; organizations must implement robust egress filtering, runtime behavioral monitoring (to catch rogue processes like .pth spawns), and strict least-privilege access for CI/CD tokens. The loop must be broken.
To further enhance your cloud security and implement Zero Trust, contact me on LinkedIn Profile or[email protected]
Frequently Asked Questions (FAQ)
What is the LiteLLM supply chain attack?
It is a severe supply chain compromise where the threat actor TeamPCP published malicious versions of the `litellm` package on PyPI to steal credentials and backdoor Kubernetes clusters.
Which versions of LiteLLM were compromised?
Versions 1.82.7 and 1.82.8 of `litellm` were compromised on the Python Package Index (PyPI).
How does the malicious `.pth` file execute?
In version 1.82.8, the attackers used a `litellm_init.pth` file. Python automatically evaluates `.pth` files in the `site-packages` directory when the interpreter starts, leading to "zero-click" execution without needing to import the package directly.
What kind of data does the TeamPCP malware steal?
The malware aggressively harvests environment variables, SSH keys, Git credentials, cloud secrets (AWS, GCP, Azure), Kubernetes tokens, database configurations, and cryptocurrency wallet files.
What should I do if my environment pulled the compromised packages?
Assume total compromise. You must immediately rotate all credentials, cloud keys, and tokens present on the machine, and hunt for persistence mechanisms like the `sysmon.service` systemd unit and unauthorized privileged Kubernetes pods.