
Inside the LiteLLM 1.107.0 supply chain compromise: Credential theft through Python startup hooks
Microsoft's analysis of the LiteLLM 1.107.0 compromise, published to PyPI and container images on 21 October 2026. The wheel shipped cook.pth, cook.py and sitecustomize.py, so a credential collector (PRIVCOLLECT) ran whenever Python started, even without importing LiteLLM. It covers AES/RSA-encrypted exfiltration to litellm.dev, a re-armable Unix loader, Defender KQL hunting queries, ATT&CK mapping and rotation guidance.
What it is
Microsoft Threat Intelligence's analysis of LiteLLM 1.107.0, published to PyPI and official container images on 21 October 2026. According to LiteLLM maintainers, stolen developer GitHub credentials redirected the release workflow to the lookalike repository Berri-AI/litellm (not BerriAI/litellm), and a second developer's credential satisfied the production approval step. Microsoft has not independently determined how the attacker first got in.
How it works
The wheel placed cook.pth, cook.py and sitecustomize.py under litellm-1.107.0.data/purelib/, so installation put them in the environment's library directory, outside the litellm folder. Python's site initialization then runs them at every interpreter start, with no import of LiteLLM.
flowchart TD
A[Python starts] --> B[cook.pth: import cook]
A --> C[sitecustomize.py, Unix]
B --> D[PRIVCOLLECT in daemon thread]
D --> E[AES-256-CBC + RSA-4096 OAEP]
E --> F[POST to www.litellm.dev/healthcheck]
C --> G[Lock /tmp/remote_code_loader.lock]
G --> H[Read GitHub domain.txt]
H -->|valid server| I[Fetch /codepy and exec]
H -->|empty| J[No second stage]- Collector:
cook.pyBase64-decodes and zlib-decompresses an embedded program. It skips work ifPRIVCOLLECT_ACTIVEis set. After an HTTP 200 upload it writes/tmp/.pc_once_72129118c59f5636c0bb. It targets developer, cloud, AI-tool and browser credentials, SSH/GPG/TLS keys, environment variables and metadata-service credentials (AWS, GCP). A separate module reads credential and model records from the LiteLLM proxy database. - Exfiltration: the archive holds
data.bin,key.binandhdr.json, sent asapplication/octet-streamwith anX-SHA256header. Staging uses temporary directories named.pc_e_*. - Loader: the
sitecustomize.pyloader is Unix-only. The attacker can change the second stage by editingdomain.txt, with no new package release.
Preconditions / Affected
Any host that installed, mirrored or built images with LiteLLM 1.107.0 and then started Python: developer workstations, CI/CD agents, test systems, containers and gateway hosts. Microsoft saw the collector run on Windows and macOS, including from a routine pip call for an unrelated dependency.
What to do
- Find every copy: installed environments, uv and pip caches, internal mirrors, lock files, build outputs and images. Prefer image digests to mutable tags. Compare against the hashes in the post's IOC section.
- Do not run
pythonorpipon a suspect environment. Inspect from a known-clean system and stop Python processes where safe. - Rebuild from verified artifacts. Deleting the
litellmdirectory leaves the three top-level startup files behind. - Rotate from a clean machine: model-provider keys, cloud and workload credentials, CI/CD secrets, source-control and registry tokens, SSH/GPG keys, AI coding-tool tokens, browser sessions, and
DATABASE_URLand stored provider keys on proxy hosts. Revoke sessions, because rotation may not invalidate active tokens. - Hunt with the post's Defender queries:
- Connections to
litellm.devandwww.litellm.dev. - Four SHA-256 hashes of the startup files (LF and CRLF variants), for example
9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25. opensslcommand lines containing.pc_e_withenc -aes-256-cbc,pkeyutlorrsautl.- Inline
python -cdatabase dumps namingLiteLLM_CredentialsTableorLiteLLM_ProxyModelTable. - A TVM exposure check:
DeviceTvmSoftwareVulnerabilities | where CveId == "TVM-2026-0003". - A
CloudProcessEventsquery foropenssl pkeyutl -encrypt -pubinwith/tmp/.pc_paths. - Longer term: hash-pinned lock files, provenance checks, review before admitting packages to mirrors, and restricted outbound egress from build and developer hosts.
Caveats
- Retrieval and execution of second-stage code was not confirmed.
domain.txtwas empty when researchers checked it. - Returned cloud metadata credentials were not confirmed in Microsoft telemetry.
- The duplicate-suppression marker and
PRIVCOLLECT_ACTIVEare not containment. A short-lived process may exit before upload, and a missing marker does not prove no collection. - Package presence or a filename alone is not a verdict. Microsoft says to correlate hashes, process ancestry,
.pc_e_staging, network destination and later identity use. - Detection names were current as of 22 October 2026 and may change.
Organisations named here
- Berri-AI/litellm
- T1102.001
- T1195.001
- T1546.018
- TVM-2026-0003
Technologies named here
- LiteLLM 1.107.0
- Microsoft Defender for Endpoint
- Microsoft Defender Antivirus
- openssl
- Windows and macOS endpoints; Unix-based systems
- Microsoft Entra ID
- Azure DevOps dependency scanning
- Docker image digests
- LiteLLM
- Python
- PyPI
- Microsoft Defender XDR
- KQL
- Docker
Techniques named here
- T1546.018 Event Triggered Execution
- T1059.006 Command and Scripting Interpreter
- T1027.013 Obfuscated Files or Information
- T1140 Deobfuscate/Decode Files or Information
- T1552.001 Unsecured Credentials
- T1552.004 Unsecured Credentials
- T1552.005 Unsecured Credentials
- T1555.003 Credentials from Password Stores
- T1082 System Information Discovery
- T1016 System Network Configuration Discovery
- T1005 Data from Local System
- T1102.001 Web Service
- T1105 Ingress Tool Transfer
- Duplicate-suppression gates
- Release workflow abuse
Threat actors named here
- Unix-oriented remote code loader in sitecustomize.py
- cook.pth
- privcollect
Related in Supply Chain


