TeamPCP’s LiteLLM PyPI Attack Used Startup-Executing Malware to Steal Credentials

Summary
Researchers found credential-stealing code in LiteLLM PyPI versions 1.82.7 and 1.82.8. Version 1.82.8 used a .pth file to run at Python startup; PyPI quarantined the project.
Key points
- The article attributes the compromise to TeamPCP, which allegedly hijacked a maintainer’s PyPI account to publish versions 1.82.7 and 1.82.8.
- Version 1.82.8 included litellm_init.pth, which Python processes at startup, allowing the payload to run without importing LiteLLM.
- The malware targeted cloud, Kubernetes, CI/CD, developer, database, and other credentials, and reportedly encrypted collected data before sending it to models[.]litellm[.]cloud.
- In Kubernetes environments, the payload reportedly attempted to create privileged pods, access host filesystems, and install a persistent backdoor.
- The article reports defacement of 15 BerriAI repositories and 182 repositories on the maintainer’s personal GitHub account.
- PyPI quarantined the LiteLLM project. The article advises affected users to rotate credentials, check for the .pth file, and audit systems and CI runners that installed the affected versions.
Article Details
- Attack Vectors
- Hijacked the LiteLLM maintainer's PyPI account and directly published malicious versions 1.82.7 and 1.82.8, bypassing the GitHub release pipeline.
- Version 1.82.8 included litellm_init.pth, which executes code on Python startup without requiring LiteLLM to be imported; version 1.82.7 triggered when litellm.proxy was imported.
- The payload harvested credentials and environment variables, encrypted collected data, and exfiltrated it to attacker infrastructure.
- In Kubernetes environments, the payload attempted cluster reconnaissance and takeover by creating privileged pods that mount the host filesystem.
- The attacker also defaced BerriAI repositories and the maintainer's personal repositories, and compromised the maintainer's GitHub account.
- Defensive Notes
- If LiteLLM 1.82.7 or 1.82.8 was installed, check site-packages for litellm_init.pth and rotate all credentials accessible to the affected system, including CI/CD secrets.
- Check for unauthorized use of potentially exposed credentials and audit CI/CD runners where either affected version was installed.
- Pin LiteLLM to a known-good version and verify releases against GitHub rather than PyPI; inspect downloaded wheels before installation.
- Pin GitHub Actions to commit SHAs rather than tags, enable 2FA or hardware keys on PyPI accounts, and separate PyPI tokens from scanning steps.
- Monitor site-packages for unexpected .pth files and investigate the reported sysmon persistence paths and C2 indicators.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| DOMAIN | aquasecurtiy[.]org | Prior-campaign domain listed by the article as a TeamPCP IOC. |
| DOMAIN | championships-peoples-point-cassette[.]trycloudflare[.]com | Prior-campaign hostname listed by the article as a TeamPCP IOC. |
| DOMAIN | investigation-launches-hearings-copying[.]trycloudflare[.]com | Prior-campaign hostname listed by the article as a TeamPCP IOC. |
| DOMAIN | litellm[.]cloud | Attacker-registered domain designed to impersonate LiteLLM's legitimate domain and used as the exfiltration infrastructure. |
| DOMAIN | models[.]litellm[.]cloud | Attacker-controlled exfiltration endpoint used by the malicious package. |
| DOMAIN | scan[.]aquasecurtiy[.]org | Prior-campaign subdomain listed by the article as a TeamPCP IOC. |
| DOMAIN | souls-entire-defined-routes[.]trycloudflare[.]com | Prior-campaign hostname listed by the article as a TeamPCP IOC. |
| HOSTNAME | tdtqy-oyaaa-aaaae-af2dq-cai[.]raw[.]icp0[.]io | ICP canister C2 hostname listed as a prior TeamPCP campaign IOC. |
| IPV4 | 46[.]151[.]182[.]203 | IP address reported for the attacker-registered litellm.cloud infrastructure. |
| URL | hxxps[:]//checkmarx[.]zone/raw | C2 URL used by the sysmon.py persistence backdoor to retrieve commands. |
| URL | hxxps[:]//models[.]litellm[.]cloud/ | Specific HTTPS exfiltration URL used by the payload to POST collected data. |
MITRE ATT&CK
T1016 · System Network Configuration DiscoveryThe payload runs ip addr and ip route to collect network configuration information.T1041 · Exfiltration Over C2 ChannelThe malware sends encrypted collected data to its exfiltration endpoint using an HTTPS POST.T1059.006 · PythonThe .pth payload launches Python code through a subprocess, including decoding and executing a base64-encoded payload.T1082 · System Information DiscoveryThe payload collects system information using commands including hostname, whoami, and uname -a.T1543.002 · Systemd ServiceThe malware installs systemd services for persistence on Linux systems and Kubernetes nodes.T1552.001 · Credentials In FilesThe payload searches local files and configuration paths for credentials, keys, tokens, and secrets.T1611 · Escape to HostIn Kubernetes, the payload creates privileged pods that mount the host root filesystem and installs persistence on the host.
People
Threat Actors
CanisterWormListed by the article as an alias of TeamPCP.DeadCatx3Listed by the article as an alias of TeamPCP.PCPcatListed by the article as an alias of TeamPCP.ShellForceListed by the article as an alias of TeamPCP.TeamPCPNamed as the actor behind the LiteLLM PyPI compromise and related defacement activity.
Malware
Products
LiteLLMsecurity researchers (including OpenSourceMalware) independently identified malicious code in the litellm PyPI package, a popular Python SDK and AI gateway proxy with over 40k GitHub stars. The threat actorPyPIsecurity researchers (including OpenSourceMalware) independently identified malicious code in the litellm PyPI package, a popular Python SDK and AI gateway proxy with over 40k GitHub stars. The threat actor TeamPCP