# litellm 1.107.0 Compromised on PyPI: Backdoored Wheels Drop a Credential Stealer and an Hourly Remote Code Loader

Attacker hijacked BerriAI's release workflow via stolen org-owner token, publishing litellm 1.107.0 wheels with .pth credential stealer and hourly RCE loader.

- Payout: Real-world hack
- Severity: critical
- Program: LiteLLM
- Analysis by: StepSecurity
- Disclosed: 2026-10-22
- Write-up quality: 9/10
- Original: https://www.stepsecurity.io/blog/litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealer
- Library page: https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealer
- Tags: area:oss domain:oss impact:data-leak impact:rce kind:incident platform:threat-intel sev:critical tech:ci-cd tech:docker tech:github-actions tech:python technique:chained technique:source-review vuln:dependency-confusion vuln:rce vuln:secrets-leak

**Target:** PyPI package wheels and Docker images (site-packages startup hooks)
**Root cause:** Stolen GitHub org-owner OAuth token (leaked via Claude Code response bodies in logged proxy) overrode branch protection and repointed the trusted release workflow to a lookalike repo Berri-AI/litellm, so the legitimate pipeline built and signed malicious artifacts.
**Steps:**
1. Attacker registers litellm.dev and GitHub account letters9813, creates dead-drop repo pythonclient-test
2. Pushes 10 commits to lookalike Berri-AI/litellm adding cook/purelib/cook.pth (`import cook`), cook.py (stealer), sitecustomize.py (loader), and `data = "cook"` in pyproject.toml [tool.maturin]
3. Uses stolen org-owner token to override branch protection and apply workflow commit 9cf97e93 pointing release source at Berri-AI/litellm@20535d8f
4. Second developer token satisfies production approval gate; wheels published to PyPI and images to GHCR/Docker Hub
5. On any Python start, cook.pth imports cook -> privcollect stealer runs on daemon thread, sets PRIVCOLLECT_ACTIVE=1
6. Stealer collects browser creds, SSH/GPG keys, cloud creds, /proc/*/environ, AI tool tokens, and dumps LiteLLM_CredentialsTable via Prisma
7. Bundle AES-256-CBC encrypted, RSA-4096 wrapped, POSTed to `http://www.litellm.dev/healthcheck` with `X-Token: XWiA8gZNa7NcX2XRoAEb`
8. sitecustomize.py forks detached daemon holding /tmp/remote_code_loader.lock; hourly fetches domain.txt from letters9813/pythonclient-test and execs `http://<host>/codepy`
**How found:** Researcher Lidor Machluf noticed unexpected files (cook.pth, cook.py, sitecustomize.py) in wheel RECORD, compared sdist pyproject.toml to git tag (found injected `data = "cook"`), and traced SLSA provenance on Docker images to lookalike repo Berri-AI/litellm at commit 20535d8f.
**Exploitation:** Supply-chain compromise: attacker with org-owner GitHub token modified the trusted release workflow so official pipeline built/signed wheels and images from a lookalike repo. Installed wheels auto-execute stealer on every Python start (no import needed), exfiltrating credentials to lookalike domain; a detached daemon polls a GitHub dead drop hourly for arbitrary Python to exec. Dead drop was empty at release so RCE stage was never armed, but channel remains live for infected hosts.
**Escalation:** Chained initial access (exposed internal LiteLLM deployment) -> token theft from logs -> branch protection override -> workflow tampering -> signed malicious release -> credential theft across dev machines, CI, and proxy DBs, plus persistent hourly RCE channel.
**Insight:** When auditing a package compromise, diff the published sdist/build config against the git tag and read SLSA provenance source URIs — a clean tag plus tampered build config plus a hyphenated lookalike repo is the tell. Also: .pth files starting with `import` and sitecustomize.py in site-packages execute on every interpreter start without any import.
