LiteLLM Compromised
At 11:39 UTC on October 21, a malicious version (1.107.0) of the LiteLLM package was uploaded to PyPI. This version was quarantined on PyPI as of 1:20 UTC.
LiteLLM Docker containers on GHCR and Docker hub also included the trojanized version of LiteLLM. These included the v1.107.0 , latest, main-latest and main-stable tags. These were removed ~13:53 UTC.
The most recent safe version is v1.106.2.
When the malicious package is installed, three files are extracted directly into the site-packages root: cook.pth, cook.py and sitecustomize.py. These packages are designed to be executed whenever a python interpreter is started.
UPDATES
14:05 UTC - added IOC table
14:15 UTC - added Attack Commits details
14:40 UTC - added Credential Stealer details, noted Docker takedown
Payload
Upon startup, the interpreter processes cook.pth, which includes a command to import cook, which loads cook.py. cook.py deobfuscates itself, runs a stealer routine and writes a maker to /tmp/.pc_once_72129118c59f5636c0bb (note this fails on Windows, as the /tmp/ path often does not exist). The stealer routine gathers system, browser, developer, cloud and AI tool secrets, encrypts them and exfiltrates to www.litellm.dev/healthcheck via a post request. This domain is attacker controlled, impersonating LiteLLM infrastructure.
Python interpreters will also attempt to execute sitecustomize.py - however, it will only run on Linux & MacOS machines. This script attempts to fetch domain.txt from a GitHub dead drop (letters9813/pythonclient-test/main/domain.txt). If it receives a response, it will attempt to download a second stage python script from http://<domain>/codepy and run it. As of the time of analysis, the domain.txt file was never populated. The repo has been taken down as of 1:30 PM UTC.
Credential Stealer
The embedded credential stealer, internally named privcollect, harvests sensitive data across 16 modules targeting browsers, cloud providers, and AI services. It extracts:
browser credentials and cookies from Chrome, Firefox, Edge, and Safari
AWS credentials from
~/.aws/, environment variables, and EC2/ECS instance metadata (IMDS)GCP service account keys and application default credentials
Azure tokens from the CLI cache
In terms of AI-specific theft, it targets API keys for OpenAI, Anthropic, Cohere, and other LLM providers stored in environment variables or config files. It also collects SSH private keys, GPG keys, and shell history files.
LiteLLM Proxy stores upstream API keys in a PostgreSQL database. The stealer queries this database directly (SELECT * FROM "LiteLLM_CredentialsTable" LIMIT 500) to extract all configured provider credentials.
Harvested data is encrypted with AES-256-CBC (key wrapped with RSA-4096) and exfiltrated over HTTP to www.litellm[.]dev/healthcheck using the hardcoded X-Token header and an Internet Explorer 7 user-agent string.
Attacker Commits
The payload originates with malicious commits made on github.com/Berri-AI/litellm. Note, this is a hyphenated variant of the legitimate BerriAI organization. This repository, not visible on GitHub, was used to inject the payload into the release pipeline.
Between 08:56 and 10:46 UTC on October 21, the attacker pushed 10 commits using the author email ckdi82fkoos@proton.me. The first nine commits were created on GitHub.com and therefore signed with GitHub's verified signature.
The first three (within 2 minutes) added the persistence files: cook.pth, cook.py, and sitecustomize.py. Four more commits bumped version numbers to 1.107.0.
After a 39-minute gap, two commits refined the payload and added the critical data = "cook" directive to pyproject.toml, which instructed the build tool to bundle the malware into the wheel.
A final commit, made 58 minutes later with a different email (Berri-AI@users.noreply.github.com) and unsigned (suggesting a different environment), added COPY cook ./cook to the Dockerfiles.
Although the Berri-AI repository is unavailable, all commits remain accessible through the parent repository due to Git's fork object sharing. The full diff is available at: github.com/BerriAI/litellm/compare/a8113b0d...20535d8f
Recommendations
Wiz customers should review our Threat Intel Center advisory: Supply Chain Attack Targeting LiteLLM .
Indicators of Compromise
| Indicator | Description | Type |
|---|---|---|
| litellm[.]dev | Attacker-controlled exfil (lookalike) | Network |
| www.litellm[.]dev/healthcheck | Exfiltration endpoint | Network |
| http://{domain}/codepy | Dynamic second-stage RCE payload (never observed active) | Network |
| X-Token: XWiA8gZNa7NcX2XRoAEb | Hardcoded exfil auth header | Network |
| /tmp/.pc_once_72129118c59f5636c0bb | Run-once marker file | Host |
| PRIVCOLLECT_ACTIVE=1 | Environment variable indicator | Host |
cook.pth Windows: 84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d Linux/macOS: 7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb | .pth persistence hook (12 bytes) | Host |
cook.py Windows: 03ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea Linux/macOS: 9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25 | Credential stealer payload (22,252 bytes) | Host |
sitecustomize.py Windows: b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465 Linux/macOS: 34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa | Loader with hourly backdoor loop (25,509 bytes) | Host |
Affected Instances
| File/Image | SHA256 |
|---|---|
| litellm-1.107.0-cp310-abi3-macosx_10_12_x86_64.whl | 7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d |
| litellm-1.107.0-cp310-abi3-macosx_11_0_arm64.whl | 0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a |
| litellm-1.107.0-cp310-abi3-manylinux_2_28_aarch64.whl | 668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6 |
| litellm-1.107.0-cp310-abi3-manylinux_2_28_x86_64.whl | 462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7 |
| litellm-1.107.0-cp310-abi3-musllinux_1_2_aarch64.whl | c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054 |
| litellm-1.107.0-cp310-abi3-musllinux_1_2_x86_64.whl | 1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00 |
| litellm-1.107.0-cp310-abi3-win_amd64.whl | 12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484 |
| ghcr.io/berriai/litellm:v1.107.0 | linux/amd64 sha256:bd1aeee419ea36da9aa2b657288da4101887be468f020ac63d22ba6ed84a3ea5 linux/arm64 sha256:56b74573eed6e4aafe4b50603dbe7853e0345f188c8e44a09f1098caf1f4bcdf |
| ghcr.io/berriai/litellm-database:v1.107.0 | linux/amd64 sha256:24581ddc30767f16ecb69d2b0517556f2cd7dea56971adb42a3d1beb97d69523 linux/arm64 sha256:827dd893c74cf621a860a66a3a447a5c732533f087589ce905573e285c0a239c |
| ghcr.io/berriai/litellm-non_root:v1.107.0 | linux/amd64 sha256:645a67d810628252d63df85dcc8824c58bcc77cf8383f4d3e6321f0ccc3ce9e4 linux/arm64 sha256:f75c8edae59b72b1ebfd617295833f465c85bb2fab9c1d60f21b496db86cb8da |
| docker.io/litellm/litellm | linux/amd64 sha256:bd1aeee419ea36da9aa2b657288da4101887be468f020ac63d22ba6ed84a3ea5 linux/arm64 sha256:56b74573eed6e4aafe4b50603dbe7853e0345f188c8e44a09f1098caf1f4bcdf |