Malicious LiteLLM 1.107.0 Wheel Steals Credentials and Installs a Persistent Backdoor

Summary
Analysis of the LiteLLM 1.107.0 macOS wheel found Python startup hooks that steal credentials and run a persistent remote-code loader. Upwind reported the payload in all seven wheels; the second stage remains unresolved.
Key points
- The analyzed macOS x86-64 wheel contains cook.pth, cook.py and sitecustomize.py; the article says all seven LiteLLM 1.107.0 PyPI wheels contain the same injected files, per Upwind.
- Python startup can trigger the payload without an application importing LiteLLM. It collects credentials and secrets, encrypts them, and sends them to www[.]litellm[.]dev/healthcheck over HTTP.
- A detached loader retrieves domain.txt from raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt, then fetches and executes Python code from the supplied host’s /codepy path hourly.
- The current second-stage domain and payload were not retrieved. Upwind reportedly said domain.txt had been empty since October 20, 2026; the article says it did not independently verify that history.
- The operator panel at www[.]litellm[.]dev appears to contain victim information, but the article says its analysis is ongoing.
- The researchers do not attribute the October compromise to TeamPCP or another actor; how the build environment or publishing credential was compromised remains unknown.
- Recommended response includes isolating affected environments, investigating relevant Python and network activity, rotating secrets accessible to affected accounts, reviewing audit logs, and rebuilding from trusted artifacts.
Article Details
- Attack Vectors
- Compromised LiteLLM 1.107.0 macOS x86-64 PyPI wheel contains cook.pth, cook.py, and sitecustomize.py, which execute automatically during Python startup.
- The credential-stealing payload collects browser credentials, keys, cloud and development secrets, environment variables, and other host information, then encrypts and uploads the collected data.
- A detached background process retrieves mutable domain configuration and repeatedly downloads and executes Python code from a remote /codepy endpoint.
- Defensive Notes
- Treat systems where Python started after the wheel was installed as potentially compromised; isolate affected hosts, containers, virtual environments, workstations, and CI runners.
- Search historical DNS, proxy, firewall, and HTTP telemetry for www.litellm.dev, especially POST /healthcheck and the reported X-Token header; also look for retrieval of the specified GitHub domain.txt path followed by Python requests to /codepy.
- Preserve relevant artifacts and telemetry. Remove the malicious files from every affected site-packages directory from a shell, then terminate the detached loader process; starting Python during remediation can trigger the payload again.
- Treat secrets accessible to affected accounts as compromised, rotate them from a known-clean system, review relevant audit logs, and rebuild affected environments from trusted artifacts.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| HOSTNAME | www[.]litellm[.]dev | Host used as the credential-exfiltration receiver and reported to appear to host an operator panel; the panel observation remains under investigation. |
| SHA256 | 20a59e5a285799e7cf7fa16cfba1c1414f1e84a8459e14207cfd4e998c2cd24b | SHA-256 of the decoded credential-stealing payload from sitecustomize.py. |
| SHA256 | 34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa | SHA-256 of sitecustomize.py, which contains a stealer variant and persistent remote-code loader. |
| SHA256 | 6ea3d8ef6cf73a72d8df24f663b7a31ce67494eeb9b0d707b93484e66675d2df | SHA-256 of the decoded credential-stealing payload from cook.py. |
| SHA256 | 7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d | SHA-256 of the malicious LiteLLM 1.107.0 macOS x86-64 wheel. |
| SHA256 | 7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb | SHA-256 of the malicious cook.pth file in the analyzed wheel. |
| SHA256 | 9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25 | SHA-256 of cook.py, which decodes and executes the credential-stealing payload. |
| URL | hxxp[:]//www[.]litellm[.]dev/healthcheck | Hard-coded HTTP endpoint used to upload encrypted credential bundles. |
| URL | hxxps[:]//raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt | Remote configuration URL the persistent loader retrieves to obtain a hostname for its second-stage request. |
| URL | hxxps[:]//www[.]litellm[.]dev | HTTPS site on the reported C2 host that appears to contain an operator panel with victim information; this observation is not yet confirmed. |
MITRE ATT&CK
T1041 · Exfiltration Over C2 ChannelThe malware exfiltrates encrypted credential bundles in HTTP POST requests to www.litellm.dev/healthcheck.T1053.003 · CronThe loader forks a detached process that polls for remote code and repeats after sleeping for an hour.T1057 · Process DiscoveryThe payload reads environment variables from other Linux processes through /proc/*/environ.T1059.006 · PythonThe loader compiles downloaded content as Python and executes it with exec().T1195.002 · Compromise Software Supply ChainThe LiteLLM 1.107.0 PyPI wheel was compromised with malicious files incorporated into the packaged artifact.T1546.010 · AppInit DLLsThe package supplies sitecustomize.py, which Python attempts to import automatically during startup.T1546.017 · Udev Rulescook.pth runs an import line during Python initialization, triggering the payload whenever Python starts in the affected environment.T1552.001 · Credentials In FilesThe payload searches home and working directories for .env files and common private-key formats.T1552.002 · Credentials in RegistryThe payload collects Kubernetes service-account tokens and Docker secrets.T1552.004 · Private KeysThe collector searches for private keys, including SSH, GPG, TLS, and Let’s Encrypt keys.T1552.005 · Cloud Instance Metadata APIThe collector targets credentials held in files and configurations for cloud services, package registries, source control, CI/CD, and developer tools.T1552.007 · Container APIThe collector reads AWS EC2/ECS role credentials, GCP service-account tokens, and Azure instance metadata.T1555.003 · Credentials from Web BrowsersThe credential collector targets browser login databases, cookies, and other browser data, including Chromium-family browsers and Firefox.T1560.002 · Archive via LibraryCollected data is archived in a gzip-compressed tar archive before transmission.T1573.001 · Symmetric CryptographyThe malware encrypts collected data with AES-256-CBC and encrypts the AES key with an embedded RSA public key.
Malware
Products
LiteLLMThe OpenSourceMalware team analyzed a wheel identifying itself as LiteLLM 1.107.0 and found a complete Python startup backdoor. The artifact does not merely contain suspicious strings or dormant test code: it installsPyPIThreat Type: PyPI supply-chain compromise, credential stealer, and persistent backdoor