Skip to content

Back to the catalog

Inside the LiteLLM 1.107.0 supply chain compromise: Credential theft through Python startup hooks
microsoft.comwriteup

Inside the LiteLLM 1.107.0 supply chain compromise: Credential theft through Python startup hooks

Microsoft's analysis of the LiteLLM 1.107.0 compromise, published to PyPI and container images on 21 October 2026. The wheel shipped cook.pth, cook.py and sitecustomize.py, so a credential collector (PRIVCOLLECT) ran whenever Python started, even without importing LiteLLM. It covers AES/RSA-encrypted exfiltration to litellm.dev, a re-armable Unix loader, Defender KQL hunting queries, ATT&CK mapping and rotation guidance.

TL;DR Explains how the trojanized LiteLLM 1.107.0 used .pth and sitecustomize startup hooks to steal credentials, with hunting queries and recovery steps.
Document

What it is

Microsoft Threat Intelligence's analysis of LiteLLM 1.107.0, published to PyPI and official container images on 21 October 2026. According to LiteLLM maintainers, stolen developer GitHub credentials redirected the release workflow to the lookalike repository Berri-AI/litellm (not BerriAI/litellm), and a second developer's credential satisfied the production approval step. Microsoft has not independently determined how the attacker first got in.

How it works

The wheel placed cook.pth, cook.py and sitecustomize.py under litellm-1.107.0.data/purelib/, so installation put them in the environment's library directory, outside the litellm folder. Python's site initialization then runs them at every interpreter start, with no import of LiteLLM.

flowchart TD
    A[Python starts] --> B[cook.pth: import cook]
    A --> C[sitecustomize.py, Unix]
    B --> D[PRIVCOLLECT in daemon thread]
    D --> E[AES-256-CBC + RSA-4096 OAEP]
    E --> F[POST to www.litellm.dev/healthcheck]
    C --> G[Lock /tmp/remote_code_loader.lock]
    G --> H[Read GitHub domain.txt]
    H -->|valid server| I[Fetch /codepy and exec]
    H -->|empty| J[No second stage]
  • Collector: cook.py Base64-decodes and zlib-decompresses an embedded program. It skips work if PRIVCOLLECT_ACTIVE is set. After an HTTP 200 upload it writes /tmp/.pc_once_72129118c59f5636c0bb. It targets developer, cloud, AI-tool and browser credentials, SSH/GPG/TLS keys, environment variables and metadata-service credentials (AWS, GCP). A separate module reads credential and model records from the LiteLLM proxy database.
  • Exfiltration: the archive holds data.bin, key.bin and hdr.json, sent as application/octet-stream with an X-SHA256 header. Staging uses temporary directories named .pc_e_*.
  • Loader: the sitecustomize.py loader is Unix-only. The attacker can change the second stage by editing domain.txt, with no new package release.

Preconditions / Affected

Any host that installed, mirrored or built images with LiteLLM 1.107.0 and then started Python: developer workstations, CI/CD agents, test systems, containers and gateway hosts. Microsoft saw the collector run on Windows and macOS, including from a routine pip call for an unrelated dependency.

What to do

  • Find every copy: installed environments, uv and pip caches, internal mirrors, lock files, build outputs and images. Prefer image digests to mutable tags. Compare against the hashes in the post's IOC section.
  • Do not run python or pip on a suspect environment. Inspect from a known-clean system and stop Python processes where safe.
  • Rebuild from verified artifacts. Deleting the litellm directory leaves the three top-level startup files behind.
  • Rotate from a clean machine: model-provider keys, cloud and workload credentials, CI/CD secrets, source-control and registry tokens, SSH/GPG keys, AI coding-tool tokens, browser sessions, and DATABASE_URL and stored provider keys on proxy hosts. Revoke sessions, because rotation may not invalidate active tokens.
  • Hunt with the post's Defender queries:
  • Connections to litellm.dev and www.litellm.dev.
  • Four SHA-256 hashes of the startup files (LF and CRLF variants), for example 9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25.
  • openssl command lines containing .pc_e_ with enc -aes-256-cbc, pkeyutl or rsautl.
  • Inline python -c database dumps naming LiteLLM_CredentialsTable or LiteLLM_ProxyModelTable.
  • A TVM exposure check: DeviceTvmSoftwareVulnerabilities | where CveId == "TVM-2026-0003".
  • A CloudProcessEvents query for openssl pkeyutl -encrypt -pubin with /tmp/.pc_ paths.
  • Longer term: hash-pinned lock files, provenance checks, review before admitting packages to mirrors, and restricted outbound egress from build and developer hosts.

Caveats

  • Retrieval and execution of second-stage code was not confirmed. domain.txt was empty when researchers checked it.
  • Returned cloud metadata credentials were not confirmed in Microsoft telemetry.
  • The duplicate-suppression marker and PRIVCOLLECT_ACTIVE are not containment. A short-lived process may exit before upload, and a missing marker does not prove no collection.
  • Package presence or a filename alone is not a verdict. Microsoft says to correlate hashes, process ancestry, .pc_e_ staging, network destination and later identity use.
  • Detection names were current as of 22 October 2026 and may change.

Organisations named here

  • Berri-AI/litellm
  • T1102.001
  • T1195.001
  • T1546.018
  • TVM-2026-0003

Technologies named here

  • LiteLLM 1.107.0
  • Microsoft Defender for Endpoint
  • Microsoft Defender Antivirus
  • openssl
  • Windows and macOS endpoints; Unix-based systems
  • Microsoft Entra ID
  • Azure DevOps dependency scanning
  • Docker image digests
  • LiteLLM
  • Python
  • PyPI
  • Microsoft Defender XDR
  • KQL
  • Docker

Techniques named here

  • T1546.018 Event Triggered Execution
  • T1059.006 Command and Scripting Interpreter
  • T1027.013 Obfuscated Files or Information
  • T1140 Deobfuscate/Decode Files or Information
  • T1552.001 Unsecured Credentials
  • T1552.004 Unsecured Credentials
  • T1552.005 Unsecured Credentials
  • T1555.003 Credentials from Password Stores
  • T1082 System Information Discovery
  • T1016 System Network Configuration Discovery
  • T1005 Data from Local System
  • T1102.001 Web Service
  • T1105 Ingress Tool Transfer
  • Duplicate-suppression gates
  • Release workflow abuse

Threat actors named here

  • Unix-oriented remote code loader in sitecustomize.py
  • cook.pth
  • privcollect