LiteLLM compromised again: infostealer and RAT found in version 1.107.0
On October 21, 2026, version 1.107.0 of LiteLLM (a popular open source proxy that lets developers route requests across dozens of LLM providers) was found to be compromised by an attacker who injected malicious code into its published Python wheels on PyPI. The official Docker image for the same version is also compromised.
The package contains two distinct malicious components: an infostealer that exfiltrates credentials and secrets on first run, and a remote access trojan (RAT) that gives the attacker the ability to run arbitrary code on infected machines at any time.
Anyone who ran pip install litellm==1.107.0
on any platform should assume credentials are compromised and check for /tmp/.pc_once_*
(the exfil has already fired if this file exists) and /tmp/remote_code_loader.lock
(the C2 daemon ran or is still running if this file exists).
The same applies to anyone who ran the official Docker image litellm/litellm:1.107.0
, or pulled it via the latest
, main-latest
, or main-stable
tags.
Update: PyPI has now quarantined version 1.107.0. The compromised Docker image (litellm/litellm:1.107.0
) is still live on Docker Hub.
What happened
The attacker exploited a directive in LiteLLM's pyproject.toml
to inject files into the compiled wheels without touching the source repository.
[tool.maturin]
data = "cook"
module-name = "litellm.rust_bridge._native"
The data = "cook"
directive tells maturin (LiteLLM's Rust/Python build tool) to bundle the contents of a directory named cook/
into the wheel's data section during the build. That directory does not exist in the source tarball or on GitHub. It was created in the compromised build environment and its contents were silently included in every compiled wheel that was then uploaded to PyPI.
Three malicious files were injected into Python's site-packages on install:
cook.pth
is a 12-byte file containing onlyimport cook
. Python processes.pth
files in site-packages at every interpreter startup, so this causescook.py
to run automatically every time Python is invoked on the machine, with no further user action required.cook.py
contains the infostealer, heavily obfuscated as a single line that decompresses and executes a 61,000-byte payload.sitecustomize.py
is the RAT. Python also executes the file at interpreter startup, before any user code runs. This file spawns a background daemon that polls the attacker's infrastructure every hour for new commands to execute.
What it steals
Once the infostealer runs, it collects the following from the infected machine:
- System information including hostname, username, OS version, running processes, and network interfaces
- Saved passwords from Chromium-based browsers (Chrome, Edge, Brave, Vivaldi, Opera) including AES-decrypted password values, and browsing history from those same browsers
- Firefox saved credentials
- SSH private keys from
~/.ssh/
- Shell history from Bash, Zsh, and Fish
- Cloud provider credentials including AWS credentials files and config, Azure authentication tokens and MSAL cache, and GCP application default credentials. It also queries the live instance metadata endpoints for AWS, GCP, and Azure to extract credentials available to the running instance.
- Docker config files and Docker Swarm secrets
- Kubernetes service account tokens
- CI/CD secrets including GitLab runner configs, Jenkins admin passwords and master keys, and HashiCorp Vault tokens
- Developer tool credentials and configuration files for Claude Code, Claude Desktop, Cursor, GitHub Copilot, Windsurf, Gemini CLI, Amazon Q, Codex CLI, Aider, Continue, HuggingFace, and others
- Git credentials,
.npmrc
,.pypirc
, and pip config files - GPG private keys and TLS private keys
- All environment variables from the current process and, on Linux, from every other running process via
/proc//environ
- The contents of the LiteLLM database directly, including all rows from
LiteLLM_CredentialsTable
(stored API keys for every provider) andLiteLLM_ProxyModelTable
(model configurations)
All collected data is encrypted with an RSA-4096 public key hardcoded in the payload and sent via HTTP POST to http://www[.]litellm[.]dev/healthcheck
. Note that this domain is attacker-controlled and is not affiliated with the legitimate LiteLLM project. A sentinel file at /tmp/.pc_once_72129118c59f5636c0bb
prevents the infostealer from running more than once per machine.
Remote access trojan
sitecustomize.py
is executed automatically by Python at startup because of its filename, before any user code runs. It forks a background daemon that acquires a lock at /tmp/remote_code_loader.lock
to prevent multiple instances, then enters an infinite loop.
Every hour, the daemon fetches the attacker's current C2 domain from a GitHub repository (raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain[.]txt
), then fetches and executes a Python payload from http://{domain}/codepy
:
async def exec_code(code):
loop = asyncio.get_running_loop()
await loop.run_in_executor(
_executor,
lambda: exec(compile(code, "", "exec"), {"__name__": "__main__"}),
)
Whatever Python the attacker serves at that endpoint runs with the full privileges of the Python process and no sandboxing. This allows the attacker to run shell commands, drop additional files, move laterally, re-exfiltrate data, or deploy any other payload on demand, on every infected machine, indefinitely.
How Aikido detects this
If you are an Aikido user, check your central feed and filter on malware issues. This will surface as a 100/100 critical issue. Aikido rescans nightly, but we recommend triggering a manual rescan now.
If you are not yet an Aikido user, you can create an account and connect your repos. Our malware coverage is included in the free plan, no credit card required.
For future protection, consider Aikido Safe Chain (open source). Safe Chain sits in your existing workflow, intercepting npm, npx, yarn, pnpm, and pnpx commands and checking packages against Aikido Intel before install.
For broader coverage across your whole team, Aikido's Device Protection gives you visibility and control over the software packages installed on your team's devices. It covers browser extensions, code libraries, IDE plugins, and build dependencies, all in one place. Stop malware before it gets installed.
Indicators of compromise
Affected package versions
litellm==1.107.0
PyPI package installed from any compiled wheel (all operating systems)- litellm-1.107.0-cp310-abi3-macosx_10_12_x86_64.whl
- SHA256:
7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d
- SHA256:
- litellm-1.107.0-cp310-abi3-macosx_11_0_arm64.whl
- SHA256:
0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a
- SHA256:
- litellm-1.107.0-cp310-abi3-manylinux_2_28_x86_64.whl
- SHA256:
462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7
- SHA256:
- litellm-1.107.0-cp310-abi3-manylinux_2_28_aarch64.whl
- SHA256:
668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6
- SHA256:
- litellm-1.107.0-cp310-abi3-musllinux_1_2_x86_64.whl
- SHA256:
1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00
- SHA256:
- litellm-1.107.0-cp310-abi3-musllinux_1_2_aarch64.whl
- SHA256:
c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054
- SHA256:
- litellm-1.107.0-cp310-abi3-win_amd64.whl
- SHA256:
12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484
- SHA256:
- litellm-1.107.0-cp310-abi3-macosx_10_12_x86_64.whl
litellm/litellm:1.107.0
Docker image (linux/amd64 and linux/arm64), including pulls via thelatest
,main-latest
, andmain-stable
tags
File indicators
cook.pth
in Python site-packages- SHA256:
7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb
- SHA256:
cook.py
in Python site-packages- SHA256:
9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25
- SHA256:
sitecustomize.py
in Python site-packages- SHA256:
34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa
- SHA256:
/tmp/.pc_once_72129118c59f5636c0bb
(sentinel file left after infostealer runs)/tmp/remote_code_loader.lock
(lock file held by the C2 daemon while running)
Network indicators
http://www[.]litellm[.]dev/healthcheck
(exfil endpoint)https://raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain[.]txt
(C2 domain lookup)- Outbound HTTP POST with
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0)
and headerX-Token: XWiA8gZNa7NcX2XRoAEb
How it works
Once you click Generate, Ollama reads this article and crafts 5 comprehension questions. Your answers are graded against the article content — general knowledge won't be enough. Score 70+ to count toward your certificate.
Questions are cached — you'll always get the same 5 for this article.