# LiteLLM Supply Chain Compromise — TeamPCP Multi-Ecosystem Campaign via Trojanized PyPI Packages

> TeamPCP compromised LiteLLM versions 1.82.7 and 1.82.8 on PyPI through a cascading supply chain attack originating from a Trivy CI/CD pipeline breach. The three-stage payload harvested credentials from 50+ categories (cloud, SSH, K8s, crypto wallets, LLM API keys), performed Kubernetes lateral movement via privileged pod deployment, and installed persistent backdoors polling attacker C2 infrastructure. With LiteLLM present in 36% of cloud environments and receiving 3.4M daily downloads, the ~3-hour exposure window before PyPI quarantine created significant downstream risk across AI/ML infrastructure.

- **Published:** 2026-03-26T12:00:00Z
- **Last reviewed:** 2026-03-26T12:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0290
- **ID:** TL-2026-0290
- **Severity:** CRITICAL (CVSS 9.8)
- **Category:** SUPPLY_CHAIN
- **Status:** MONITORING
- **Actor:** TeamPCP (Russia)
- **Detections:** 9 · **IOCs:** 52 (full data via the Threadlinqs MCP server — Purple tier)

## Description

On March 24, 2026, threat actor TeamPCP published trojanized versions of LiteLLM (1.82.7 and 1.82.8) to PyPI, marking the culmination of a month-long multi-ecosystem supply chain campaign that previously compromised Aqua Security's Trivy, Checkmarx KICS, npm packages, Docker Hub images, and VS Code extensions.

## Attack Origin — Trivy CI/CD Breach

The campaign began on February 28, 2026, when TeamPCP (operating as 'hackerbot-claw') exploited a misconfigured pull_request_target workflow in Aqua Security's Trivy repository. This allowed them to steal an organization-scoped Personal Access Token (ORG_REPO_TOKEN) belonging to the aqua-bot service account, which had permissions across 33+ workflows. Using this stolen token, TeamPCP force-pushed malicious commits to 75 of 76 trivy-action release tags and all 7 setup-trivy tags on March 19, 2026. The compromised GitHub Actions extracted secrets from runner memory by reading /proc/<pid>/mem on GitHub-hosted runners.

## Cascading Compromise

TeamPCP leveraged the Trivy breach to pivot across multiple ecosystems: malicious Docker images (aquasec/trivy:0.69.5, 0.69.6) were pushed to Docker Hub; 28 npm packages under the @EmilGroup scope were infected with CanisterWorm; all 35 Checkmarx KICS GitHub Action tags were hijacked; and two malicious VS Code extensions were published to OpenVSX. The LiteLLM compromise was the final and highest-impact stage.

## LiteLLM Payload Analysis

**Version 1.82.7** (published 10:39 UTC): Modified proxy_server.py to drop a double-base64-encoded payload to disk as p.py, executing when litellm --proxy runs or litellm.proxy.proxy_server is imported.

**Version 1.82.8** (published 10:52 UTC, 13-minute pivot): Used a more sophisticated persistence mechanism via litellm_init.pth (34,628 bytes), a Python path configuration file that executes arbitrary code during interpreter initialization of any Python process. The payload was double-base64 encoded and launched via subprocess, bypassing simple inspection.

## Three-Stage Payload

**Stage 1 — Credential Harvesting**: The payload collected credentials from 50+ categories including: SSH private keys and configs, .env files, AWS/GCP/Azure cloud credentials, Kubernetes configs and service account tokens, Docker configs, database passwords, .gitconfig, shell history, cryptocurrency wallet files, environment variables, CI/CD secrets, and cloud metadata endpoints (IMDS, container credentials).

**Stage 2 — Encrypted Exfiltration**: Collected data was encrypted using AES-256-CBC with a random 32-byte session key generated via OpenSSL. The session key was then encrypted with a hardcoded 4096-bit RSA public key using OAEP padding. The encrypted archive (tpcp.tar.gz) was POSTed to attacker-controlled infrastructure at models.litellm.cloud (version 1.82.8) or checkmarx.zone/raw (version 1.82.7).

**Stage 3 — Kubernetes Lateral Movement & Persistence**: If a Kubernetes service account token was present, the malware read all cluster secrets across all namespaces, created privileged alpine:latest pods (named node-setup-*) on every node in the kube-system namespace with host filesystem mounts, and installed a persistent backdoor at /root/.config/sysmon/sysmon.py on each node. Local persistence was achieved via a systemd user service (sysmon.service) installed at ~/.config/systemd/user/sysmon.service, with the backdoor polling C2 infrastructure for commands.

## Bug in Malware

The .pth mechanism in version 1.82.8 contained an unintentional fork bomb: the .pth file spawned child processes via subprocess.Popen, which re-triggered the same .pth file on startup, causing exponential process creation that crashed some test systems. This accidental behavior may have accelerated detection.

## Impact & Exposure

LiteLLM is a widely-used AI proxy library present in 36% of cloud environments (per Wiz) with approximately 3.4 million daily PyPI downloads. It is a dependency of major AI/ML frameworks including DSPy, MLflow, CrewAI, OpenHands, and Arize Phoenix. The malicious versions were available for approximately 3 hours (10:39 UTC to ~13:52 UTC on March 24) before PyPI quarantined them. The maintainer's GitHub account appeared compromised, as they closed the critical security issue (#24512) as 'not planned' without acknowledgment, and the account showed 160+ commits created within minutes.

## C2 Infrastructure

TeamPCP operated C2 infrastructure on bulletproof hosting (AS205759) across three IP addresses. They abused Cloudflare Tunnels for fallback exfiltration and used Internet Computer Protocol (ICP) canisters for persistence dropper distribution. The infrastructure included typosquatted domains mimicking legitimate security vendor properties (models.litellm.cloud, checkmarx.zone, scan.aquasecurtiy.org).

## MITRE ATT&CK

- T1195 Supply Chain Compromise
- T1078 Valid Accounts
- T1059 Command and Scripting Interpreter
- T1543 Create or Modify System Process
- T1574 Hijack Execution Flow
- T1611 Escape to Host
- T1027 Obfuscated Files or Information
- T1036 Masquerading
- T1552 Unsecured Credentials
- T1082 System Information Discovery
- T1087 Account Discovery
- T1610 Deploy Container
- T1005 Data from Local System
- T1530 Data from Cloud Storage
- T1071 Application Layer Protocol
- T1573 Encrypted Channel
- T1090 Proxy
- T1041 Exfiltration Over C2 Channel
- T1496 Resource Hijacking

## Sources

- [Trend Micro: Your AI Gateway Was a Backdoor — Inside the LiteLLM Supply Chain Compromise](https://www.trendmicro.com/en_us/research/26/c/inside-litellm-supply-chain-compromise.html)
- [Wiz: TeamPCP Trojanizes LiteLLM in Continuation of Campaign](https://www.wiz.io/blog/threes-a-crowd-teampcp-trojanizes-litellm-in-continuation-of-campaign)
- [Snyk: Trivy GitHub Actions Supply Chain Compromise](https://snyk.io/articles/trivy-github-actions-supply-chain-compromise/)
- [FutureSearch: LiteLLM PyPI Supply Chain Attack](https://futuresearch.ai/blog/litellm-pypi-supply-chain-attack/)
- [GitHub Issue #24512: CRITICAL — Malicious LiteLLM_init.pth in LiteLLM PyPI Package](https://github.com/BerriAI/litellm/issues/24512)
- [Trend Micro IOC File](https://documents.trendmicro.com/assets/txt/Your-AI-Gateway-Was-A-Backdoor_IOCS-iIalxJu.txt)
- [Endor Labs: LiteLLM 1.82.7 and 1.82.8 Supply Chain Compromise](https://www.endorlabs.com/learn/litellm-1-82-7-and-1-82-8-supply-chain-compromise)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0290
