TeamPCP Used Malicious LiteLLM Releases to Steal Credentials

Summary
Forcepoint traces how TeamPCP used a compromised Trivy build tool to publish malicious LiteLLM versions that stole AI, cloud and developer credentials, exfiltrated data, and installed a persistent backdoor.
Key points
- A compromised Trivy binary in LiteLLM's CI/CD pipeline scraped runner memory and stole the PyPI publishing token, which attackers used to release malicious LiteLLM versions 1.82.7 and 1.82.8.
- Version 1.82.7 injected a Base64-encoded payload into proxy_server.py, which ran when the LiteLLM proxy started.
- Version 1.82.8 added a .pth file that executed at Python interpreter startup, even when LiteLLM was not explicitly imported.
- The payload searched environment variables and configuration files for AI provider keys, cloud credentials, Kubernetes configuration, and AWS credentials.
- Collected data was encrypted with AES-256-CBC and exfiltrated to models[.]litellm[.]cloud.
- A persistence script polled checkmarx[.]zone for code to download and run as a background process.
- Forcepoint says it categorized the credential-harvesting domain and added hashes of the malicious package versions to its blocklist.
Article Details
- Attack Vectors
- TeamPCP compromised Trivy using impersonated commits and spoofed maintainer identities, then poisoned its repository and triggered an automated release pipeline.
- A compromised Trivy binary in LiteLLM's CI/CD build process scraped the runner's memory and exfiltrated the PYPI_PUBLISH token.
- Using the stolen token, attackers published malicious LiteLLM versions 1.82.7 and 1.82.8 while bypassing LiteLLM's source repository.
- Version 1.82.7 injected a Base64-encoded payload into proxy_server.py, which executed when the LiteLLM proxy started.
- Version 1.82.8 added litelllm_init.pth to site-packages, causing the payload to execute at Python interpreter startup.
- The payload collected environment variables, cloud and AI service credentials, and local files including ~/.kube/config and ~/.aws/credentials, then encrypted the data and exfiltrated it.
- A persistence script polled a remote URL, downloaded returned files to /tmp/pglog, made them executable, and ran them as background processes.
- Defensive Notes
- The article says the credential-harvesting URL domain was categorized.
- Hashes of the malicious PyPI versions were added to the publisher's blocklist.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| SHA1 | 2d94efc6d49e05b314a9da55804f6a0d57154b18 | Hash identified for the malicious litelllm_init[.]pth file in LiteLLM 1.82.8. |
| SHA1 | 9e7587b990ae57319a6afedeba3b8873f6238206 | Hash identified for the malicious proxy_server[.]py file in LiteLLM 1.82.7. |
| URL | hxxps[:]//checkmarx[.]zone/raw | Polling and payload-delivery URL used by the persistence backdoor. |
| URL | hxxps[:]//models[.]litellm[.]cloud/ | Exfiltration URL used by the payload to send collected data. |
MITRE ATT&CK
T1005 · Data from Local SystemThe payload collected local files, including ~/.kube/config and ~/.aws/credentials.T1027.013 · Encrypted/Encoded FileThe LiteLLM 1.82.7 payload was Base64-encoded before being injected into proxy_server.py.T1059.006 · PythonThe malicious .pth file and persistence script executed through Python.T1071.001 · Web ProtocolsThe persistence backdoor periodically polled a remote URL over HTTP(S) for a response containing a URL.T1105 · Ingress Tool TransferThe backdoor downloaded a file from the polling response to /tmp/pglog and ran it.T1119 · Automated CollectionThe script automatically scanned environment variables and configuration files for credentials and other data.T1195.002 · Compromise Software Supply ChainTeamPCP poisoned Trivy and published malicious LiteLLM package versions through the software supply chain.T1546.017 · Udev RulesThe litelllm_init.pth file executed at Python interpreter startup without requiring an import.T1552.001 · Credentials In FilesThe payload searched configuration files and local files, including ~/.aws/credentials and ~/.kube/config, for credentials.T1552.005 · Cloud Instance Metadata APIThe payload collected cloud credentials described as cloud metadata for AWS, GCP, and Azure.T1560.001 · Archive via UtilityCollected data was saved in the archive tpcp.tar[.]gz before exfiltration.