Malicious LiteLLM versions linked to TeamPCP supply chain attack

TeamPCP backdoored LiteLLM v1.82.7–1.82.8, likely via Trivy CI/CD, adding tools to steal credentials, move in Kubernetes, and keep persistent access.

Threat actor TeamPCP compromised LiteLLM versions 1.82.7 and 1.82.8, likely through a Trivy CI/CD breach. LiteLLM, with over 95 million monthly downloads, helps developers route LLM requests via a single API.

The malicious releases, now removed from PyPI, included a multi-stage payload: a credential harvester targeting SSH keys, cloud data, wallets, and .env files; tools for lateral movement in Kubernetes via privileged pods; and a persistent systemd backdoor connecting to a remote server for further payloads.

On March 24, 2026, Endor Labs discovered that LiteLLM versions 1.82.7 and 1.82.8 on PyPI were backdoored, despite no malicious code in the GitHub repo.

The compromised versions execute a hidden payload on import, while v1.82.8 also installs a .pth file to trigger it on any Python run. Version 1.82.6 remains the last safe release.

The malware launches a three-stage attack: stealing credentials (SSH keys, cloud tokens, Kubernetes secrets, wallets, .env files), spreading across Kubernetes clusters via privileged pods, and installing a persistent systemd backdoor that fetches more payloads. Attackers encrypted stolen data before exfiltrating it. The campaign is linked to TeamPCP, already tied to attacks across multiple ecosystems including GitHub Actions, Docker Hub, npm, OpenVSX, and PyPI.

“The malicious code resides in a single file within the litellm wheel distributed on PyPI: litellm/proxy/proxy_server.py. The attacker inserted 12 lines at line 128, between two unrelated legitimate code blocks (the REALTIME_REQUEST_SCOPE_TEMPLATE dictionary and the showwarning function).” reads the report published by Endor Labs. “The GitHub source at the corresponding commit does not contain these lines — the injection was performed during or after the wheel build process.”

The malicious code was hidden inside the LiteLLM PyPI package, specifically in proxy_server.py, where 12 malicious lines were inserted during or after the wheel build.

he 12-line injection in proxy_server.py (lines 128–139). The malicious code sits between the legitimate REALTIME_REQUEST_SCOPE_TEMPLATE dictionary (line 122) and the showwarning function (line 141). Line 130 contains the active base64 payload (34,460 characters); lines 131–132 contain commented-out earlier iterations.

This code runs automatically when the module is imported, silently decoding and executing a payload. It avoids detection by using subprocess calls instead of flagged methods like exec().

Version 1.82.8 adds a more dangerous method: a .pth file that executes the payload on every Python startup, even if LiteLLM is never used. It runs in the background, making detection harder and spreading impact across any Python process in that environment.

“This makes 1.82.8 significantly more dangerous: any Python script, test runner, or tool invoked in an environment where litellm is installed will silently trigger the credential harvester in the background.” continues the report.

The malware works in three stages. First, it launches an orchestrator that collects and encrypts stolen data before sending it to a remote server. Second, a credential harvester scans the system for sensitive data, including SSH keys, cloud credentials, Kubernetes secrets, environment files, databases, wallets, and system logs. It can also move laterally by deploying privileged pods across Kubernetes nodes.

Finally, it installs a persistent backdoor as a systemd service that regularly contacts a remote server, downloads new payloads, and maintains long-term access while blending in with normal system processes.

The malicious code reveals three development stages left in the package as commented base64 blobs. The first version used exec() and basic obfuscation, already targeting credentials and using the same C2 and persistence. The second included both old and new harvester code, showing a transition phase. The final version refined delivery, replacing exec() with subprocess techniques to evade detection, while keeping the same targets and infrastructure.

The malware uses two C2 domains: one to receive encrypted stolen data and another to deliver additional payloads. Its obfuscation relies on multiple nested base64 layers and standard library code to appear harmless. Stolen data is protected with RSA+AES encryption, and the package was rebuilt with valid hashes, making detection difficult without comparing it to the original source.

Endor Labs attributes the attack to TeamPCP with high confidence, citing strong overlaps with earlier incidents reported by Wiz. Key indicators match exactly, including the same C2 domain (checkmarx.zone), identical persistence files (sysmon.py and sysmon.service), the “System Telemetry Service” name, 50-minute beaconing, the same kill switch logic, and the tpcp.tar.gz exfiltration archive. Encryption methods and Kubernetes persistence techniques are also consistent.

Timeline data supports this attribution, the researchers reported that the malicious LiteLLM versions were released shortly after the KICS compromise, with rapid iteration between versions.

TeamPCP repeatedly leverages stolen credentials to pivot across ecosystems, targeting security tools to maximize access to sensitive data and infrastructure.

“This campaign is almost certainly not over. TeamPCP has demonstrated a consistent pattern: each compromised environment yields credentials that unlock the next target.” concludes the report. “The litellm compromise is the latest escalation in a month-long campaign that began with a single incomplete incident response. On February 28, an autonomous bot exploited a workflow vulnerability in Trivy and stole a PAT. Aqua remediated the surface-level damage but left residual access. Three weeks later, TeamPCP leveraged that opening — and in five days crossed five supply chain ecosystems: GitHub Actions, Docker Hub, npm, OpenVSX, and now PyPI.”

Follow me on Twitter: @securityaffairs and Facebook and Mastodon

Pierluigi Paganini

(SecurityAffairs – hacking, TeamPCP)

Leave a Reply

Your email address will not be published. Required fields are marked *

Subscribe to our Newsletter