Threat reportSupply ChainTL-2026-4326

LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI Developer Credentials

highACTIVE

LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI (TL-2026-4326), also tracked as litellm 1.107.0 compromise, is a high-severity supply-chain compromise, first published 2026-10-24. It has no confirmed attribution, affects BerriAI litellm (PyPI package), maps to 17 MITRE ATT&CK techniques (T1005, T1027.013, T1059.006), and is covered by 9 detection rules and 30 indicators of compromise.

Severity
HIGHAssessed severity
CVEs
0None referenced
Techniques
17MITRE ATT&CK
Actors
0Not attributed
Detection rules
9SPL · KQL · Sigma
IOCs
30Indicators of compromise

Key facts for TL-2026-4326

Threat ID
TL-2026-4326
Also known as
litellm 1.107.0 compromise, privcollect
Severity
HIGH
Status
ACTIVE
Category
SUPPLY_CHAIN
First published
Last reviewed
Attribution confidence
LOW
Motivation
UNKNOWN
Target sectors
technology, cloud, ai-ml, software-development
Target regions
Global
Detection rules
9
Indicators of compromise
30

Malware and tooling in LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI

Malware and tooling: Python, privcollect

How LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI works

On 2026-10-21 a malicious litellm==1.107.0 was published to PyPI and to GHCR/Docker Hub container tags after the release workflow was pointed at a lookalike 'Berri-AI/litellm' repository. The package drops cook.pth, cook.py and sitecustomize.py, which run at every Python interpreter start, harvest cloud, Kubernetes, SSH, browser, environment and AI-assistant credentials, and exfiltrate them encrypted, while a second loader polls a GitHub dead drop for arbitrary remote Python.

litellm is a widely used Python AI/LLM gateway (Socket reports roughly 23 million weekly downloads before the compromise). On 2026-10-21 seven malicious litellm==1.107.0 wheels (macOS x86_64/arm64, manylinux and musllinux x86_64/aarch64, Windows amd64) were uploaded to PyPI between about 11:39:51 and 11:40:13 UTC, and container images (ghcr.io/berriai/litellm v1.107.0, litellm-database, litellm-non_root, docker.io/litellm/litellm, plus the latest, main-latest and main-stable tags) were published from about 11:46 UTC. Socket's scanner flagged the wheels about seven minutes after publication. PyPI quarantined the release around 13:20 UTC, GHCR images were removed around 13:51-13:53 UTC and Docker Hub tags were repointed to clean images around 14:20 UTC. Wiz reported roughly 49,000 downloads. The last known safe release is 1.106.2.

The attack operated entirely in packaging. Commit 783c43bc (09:48:21 UTC) added data = "cook" to the [tool.maturin] section of pyproject.toml so that a malicious cook/ directory was bundled into the wheel's .data/purelib tree and extracted into the site-packages root. A later commit, 20535d8fa (10:46:29 UTC), added COPY directives to the Dockerfiles. According to StepSecurity, ten commits were pushed to a lookalike repository Berri-AI/litellm (hyphenated, versus the legitimate BerriAI/litellm), stacked on the real v1.107.0 tag; nine were authored by ckdi82fkoos@proton.me and displayed GitHub 'Verified' badges (a web-editor default, not identity proof) and one by Berri-AI@users.noreply.github.com was unsigned. The container build provenance records the release workflow dispatched with source_owner 'Berri-AI', and the lookalike revision matched the PyPI wheel payloads byte for byte. Sources disagree on how the workflow was subverted: StepSecurity reports a stolen organization owner token (bypassing branch protection at 10:08:34 UTC) obtained from GitHub CLI OAuth tokens found in application logs of an internal LiteLLM deployment; Datadog reports stolen GitHub CLI OAuth tokens from three engineers' accounts; Socket and Endor Labs state the authorization mechanism is undetermined from available evidence. Datadog notes this is LiteLLM's second compromise in 2026, with earlier incidents linked to TeamPCP, and that no connection between the campaigns was established.

Three files execute whenever any Python interpreter starts, without litellm ever being imported: cook.pth (executes import cook via the .pth mechanism), cook.py (the 'privcollect' credential stealer, about 61 KB of Base64/zlib-compressed Python, run on a daemon thread, with PRIVCOLLECT_ACTIVE=1 set to suppress re-entry) and sitecustomize.py (a remote code loader with an embedded fallback copy of the stealer). The stealer runs 16 collection modules covering AWS (including IMDSv2 and ECS task credentials), Azure and GCP (including service-account tokens), Kubernetes, Docker, GitHub CLI, Vault, Terraform and CI systems (GitLab Runner, Jenkins), Git/npm/PyPI/.netrc/.env files, SSH and GPG private keys, TLS certificates, Chromium and Firefox login databases, cookies and history, environment variables and /proc/<pid>/environ for all processes, and AI tooling configuration (Codex ~/.codex/auth.json, Claude ~/.claude/.credentials.json, Gemini ~/.gemini/oauth_creds.json, Cursor ~/.cursor/mcp.json, plus Copilot, Windsurf, Kiro, Zed, Continue, OpenCode and Hugging Face). On LiteLLM proxy deployments with DATABASE_URL set it queries the Prisma tables LiteLLM_CredentialsTable and LiteLLM_ProxyModelTable for upstream provider API keys and model configurations.

Data is packed into a tar.gz (hdr.json, data.bin, key.bin), encrypted with a random AES-256-CBC key wrapped with an RSA-4096 OAEP-SHA256 key (public key SHA-256 fingerprint a898fd08ad220fed52488906eb45d196f332b972ad5d85214e7726545ecc4218) and POSTed to http://www.litellm.dev/healthcheck with headers X-SHA256 and X-Token: XWiA8gZNa7NcX2XRoAEb, up to four attempts with a 120-second timeout, using an MSIE 7.0 User-Agent per Aikido. The marker /tmp/.pc_once_72129118c59f5636c0bb is written only after an HTTP 200 response. The loader in sitecustomize.py forks a detached daemon (Linux/macOS; it fails silently on Windows), takes /tmp/remote_code_loader.lock, polls https://raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt every 3,600 seconds, extracts a hostname, downloads Python from http://<host>/codepy and runs it with compile()/exec() without any signature or hash verification, giving the operator arbitrary code execution. Earlier dead-drop values localhost:18909 and test.test.com:18909 suggest testing. The dead drop was emptied on 2026-10-20 and again at about 13:01 UTC on 2026-10-21; after disclosure the letters9813 account and repository were deleted. Because the loader persists as a process and the files persist in site-packages, uninstalling litellm does not remove the implant.

Pre-staging: litellm.dev was registered on 2026-10-13 at 00:45 UTC (behind Cloudflare) and the letters9813 GitHub account was created at 06:43 UTC the same day, about a week before the attack. Wiz observed post-exploitation credential validation (sts:GetCallerIdentity followed by Bedrock/LLM API enumeration) from roughly 16:20 to 17:01 UTC on 2026-10-21, about 4.5 hours after exfiltration; Wiz lists IPs 168.100.8.57 and 165.227.201.8 among its network IOCs. Socket noted no confirmed evidence of successful credential theft from individual deployments at the time of its report. No threat actor is attributed in the sources.

MITRE ATT&CK techniques used in TL-2026-4326

Collection

T1005 Data from Local System

Defense Evasion

T1027.013 Encrypted/Encoded File; T1140 Deobfuscate/Decode Files or Information

Execution

T1059.006 Python

Command and Control

T1071.001 Web Protocols; T1102.001 Dead Drop Resolver

Initial Access

T1078 Valid Accounts; T1195.001 Compromise Software Dependencies and Development Tools

Discovery

T1082 System Information Discovery

Credential Access

T1528 Steal Application Access Token; T1539 Steal Web Session Cookie; T1552.001 Credentials In Files; T1552.004 Private Keys; T1552.005 Cloud Instance Metadata API; T1555.003 Credentials from Web Browsers

Persistence

T1546.018 Python Startup Hooks

Resource Development

T1583.001 Domains

Affected products and versions in LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI

  • BerriAI — litellm (PyPI package)
    Vulnerable versions: 1.107.0
    Fixed in: 1.106.2 (last known safe release)
  • BerriAI — litellm container images (ghcr.io/berriai/litellm, litellm-database, litellm-non_root, docker.io/litellm/litellm)
    Vulnerable versions: v1.107.0; latest; main-latest; main-stable (as published 2026-10-21 11:46-14:20 UTC)
    Fixed in: v1.106.2 by digest

Remediation for LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI

Patches

  • Pin to litellm==1.106.2 (last known safe release); 1.107.0 release candidates rc1 and rc2 were built from the legitimate repository

Immediate actions

  • Block litellm==1.107.0 and the affected image tags (v1.107.0, latest, main-latest, main-stable) and digests; grep lockfiles, caches, build logs and container layers for 1.107.0
  • If Python ran after installation, isolate the host or container before running further Python and preserve evidence with trusted tooling
  • Kill the process holding /tmp/remote_code_loader.lock and delete cook.pth, cook.py, sitecustomize.py and their __pycache__ files from every site-packages directory
  • Block litellm.dev and www.litellm.dev at DNS/egress and alert on raw.githubusercontent.com/letters9813/ requests and on any request path ending in /codepy (indicates remote code execution occurred)
  • Rotate all potentially exposed credentials from a clean system: cloud keys and sessions, SSH/GPG keys, registry tokens (PyPI, npm, GitHub), Kubernetes and Vault tokens, provider API keys stored in the LiteLLM proxy database, and LiteLLM master/salt/virtual keys

Workarounds

  • Hunt for /tmp/.pc_once_72129118c59f5636c0bb, /tmp/remote_code_loader.lock, PRIVCOLLECT_ACTIVE=1 and the payload hashes; treat any host with these artifacts as actively compromised

Longer-term hardening

  • Rebuild virtual environments and containers from reviewed artifacts rather than cleaning in place; pin container images by digest
  • Restrict release builds to approved repository identities and audit workflow_dispatch inputs such as source_owner
  • Compare published distributions against the intended source, including wheel .data directories
  • Separate release credentials from testing and dependency-installation environments and avoid long-lived tokens in application logs
  • Review CloudTrail, identity-provider and repository audit logs for use of exposed credentials, including GetCallerIdentity calls around install time followed by external use

Weaknesses (CWE) in LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI

CWE-506, CWE-829

Timeline of LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI

  • Attacker domain litellm.dev registered (00:45 UTC, behind Cloudflare) and GitHub account letters9813 created (06:43 UTC), about a week before the attack (StepSecurity).
  • GitHub dead-drop file domain.txt emptied at 09:15 UTC after testing; historical pointer values included localhost:18909 and test.test.com:18909 (StepSecurity, Socket).
  • Wiz observed post-exploitation credential validation (sts:GetCallerIdentity, then Bedrock/LLM API enumeration) between about 16:20 and 17:01 UTC, roughly 4.5 hours after exfiltration.
  • GitHub dead drop returned an empty body at 13:01 UTC; PyPI quarantined 1.107.0 around 13:20 UTC; GHCR images removed around 13:51-13:53 UTC; Docker Hub tags repointed to clean images around 14:20 UTC.
  • Socket's AI scanner flagged the malicious wheels at 11:46:30 UTC, about seven minutes after publication; Socket reported the compromise the same day.
  • Seven malicious litellm==1.107.0 wheels uploaded to PyPI at about 11:39:51-11:40:13 UTC; infected container images and latest/main-latest/main-stable tags published from about 11:46 UTC.
  • Container build (run 39587059944) ran 10:51-11:06 UTC with provenance recording source_owner 'Berri-AI' instead of 'BerriAI' (Socket).
  • Ten commits pushed to lookalike repository Berri-AI/litellm between 08:56 and 10:46 UTC, including 783c43bc adding data = "cook" to the Maturin config and 20535d8fa adding payload COPY directives to the Dockerfiles; a stolen org owner token bypassed branch protection at 10:08:34 UTC per StepSecurity.
  • GBHackers published coverage citing the Socket report; the letters9813 account and dead-drop repository were later reported deleted.

Sources cited for LiteLLM Supply Chain Compromise (litellm 1.107.0) Targets AI

Detection coverage for TL-2026-4326

As of 2026-10-24, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-4326 across Splunk SPL, Microsoft KQL and Sigma, covering 30 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.

9 detection rules (Splunk SPL, Microsoft KQL, Sigma) · Blue and above. Compare plans
30 indicators of compromise · Red and above. Compare plans

Further reading

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Live intelligence console

Threat level
Fig. 01 · Threat weatherIndexing the archive…
1 square = 1 threat · click to open

Latest Threats