PyPI package with 3.6m daily downloads is compromised

By Paul McCarty & Juan Aguirre

PyPI package with 3.6m daily downloads is compromised

LiteLLM, one of the most popular Python packages for working with LLMs, has been compromised. Versions 1.82.7 and 1.82.8 contain malware that steals credentials from over 50 sources, targets cryptocurrency wallets across 10+ platforms, and can take over entire Kubernetes clusters.

The package sees roughly 3.6 million downloads per day. The last clean version is 1.82.6.

If you're running either of these versions, your system is compromised. Stop reading and start rotating credentials.

For everyone else, here's what happened.

Two Versions, Two Injection Techniques

The attacker compromised two consecutive versions using different injection methods—suggesting either iteration or an attempt to evade detection.

Version 1.82.8 uses Python's .pth file mechanism. These files are automatically processed when Python starts, and can execute arbitrary code. The package includes litellm_init.pth—a 34KB file (abnormally large for a .pth file) that decodes and executes a base64-encoded payload. You don't even need to import litellm. Just starting Python is enough.

Version 1.82.7 takes a different approach. A 12-line loader is injected directly into litellm/proxy/proxy_server.py at line 128, between legitimate code. Because this module is imported at the package level, the malicious code executes immediately on import litellm.

Both payloads do the same thing once executed.

The Data Theft Operation

Once the payload runs, it performs a systematic sweep of the infected system. This isn't opportunistic grabbing—it's a comprehensive credential harvesting operation that knows exactly where to look.

Cloud Infrastructure

The malware targets all major cloud providers:

AWS - What it steals: ~/.aws/credentials, ~/.aws/config, environment variables, EC2 instance metadata (IMDS v1 and v2), Secrets Manager contents, SSM parameters

GCP - What it steals: ~/.config/gcloud/ recursively, application default credentials, service account keys

Azure - What it steals: ~/.azure/ recursively, all Azure environment variables | | Kubernetes | ~/.kube/config, service account tokens, all secrets across all namespaces |

For AWS, the malware implements full SigV4 request signing to call Secrets Manager and SSM Parameter Store APIs directly. It's not just grabbing files—it's actively querying your cloud services.

Cryptocurrency Wallets

The malware targets wallets across 10+ blockchain platforms:

  • Bitcoin, Litecoin, Dogecoin, Zcash, Dash, Monero configs
  • Ethereum keystores
  • Solana validator keypairs, vote account keypairs, identity JSON
  • Cardano signing and verification keys
  • Ripple configurations
  • It performs recursive searches for files matching patterns like *-keypair.json in common Solana directories.

    Everything Else

    The list goes on:

  • SSH keys (private keys, authorized\_keys, known\_hosts, host keys)
  • Database credentials (MySQL, PostgreSQL, Redis, MongoDB)
  • Git credentials and configs
  • Docker credentials
  • NPM tokens
  • TLS/SSL private keys and certificates
  • CI/CD configs (Terraform state files, GitLab CI, Jenkins, Drone)
  • Environment files (.env, .env.production, etc.)
  • Shell history files
  • Slack and Discord webhooks
  • /etc/passwd and /etc/shadow
  • The malware walks directories recursively up to 6 levels deep, searching /opt, /srv, /var/www, /app, /data, /var/lib, and /tmp for anything valuable.

    Kubernetes Cluster Takeover

    This is where it gets serious.

    If the malware detects it's running inside a Kubernetes pod (by checking for a service account token at /var/run/secrets/kubernetes.io/serviceaccount/token), it attempts a full cluster takeover.

    The attack flow:

  • Enumerates all nodes in the cluster via the Kubernetes API
  • For each node, creates a privileged pod named node-setup-{node_name} in the kube-system namespace
  • Each pod mounts the host filesystem at /host, runs with hostPID: true, hostNetwork: true, and privileged: true
  • Inside each pod, drops the persistence mechanism directly onto the host via chroot
  • Here's what the malicious pod spec looks like:

    This effectively gives the attacker root access to every node in your cluster.

    Persistence

    The malware doesn't just steal and leave. It installs a backdoor.

    It drops ~/.config/sysmon/sysmon.py (disguised as "System Telemetry Service") and creates a systemd user service at ~/.config/systemd/user/sysmon.service:

    The persistence dropper:

  • Sleeps 5 minutes before starting (evasion)
  • Polls https://checkmarx.zone/raw every \~50 minutes for commands
  • Downloads and executes binary payloads
  • Has a kill switch: if the URL contains "youtube.com", execution is skipped
  • Exfiltration

    All stolen data is encrypted before exfiltration using a hybrid encryption scheme:

  • Data is collected to a temporary file
  • A random AES-256-CBC session key is generated
  • Data is encrypted with the session key
  • The session key is encrypted with a hardcoded RSA-4096 public key (OAEP padding)
  • Everything is bundled as tpcp.tar.gz and sent via HTTPS POST to https://models.litellm.cloud/
  • Only the attacker has the private key. There's no way to decrypt what was stolen.

    The domain models.litellm.cloud is designed to look like legitimate litellm infrastructure (the real site is litellm.ai). In network logs, it blends right in.

    Attribution

    The exfiltration archive is named tpcp.tar.gz—"tpcp" stands for TeamPCP, the same threat actor behind the Trivy and KICS GitHub Actions compromises earlier this year.

    That said, attribution is always complicated. What we know for certain: both campaigns share infrastructure patterns, code style, and the "TeamPCP" signature. Whether it's the same individual, a group, or a copycat using the same toolkit is harder to say definitively.

    Indicators of Compromise

    Network:

  • https://models.litellm.cloud/ — exfiltration endpoint
  • https://checkmarx.zone/raw — C2 for second-stage payloads
  • Queries to 169.254.169.254 (EC2 metadata service)
  • Files:

  • **/site-packages/litellm_init.pth — malicious .pth file (v1.82.8)
  • ~/.config/sysmon/sysmon.py — persistence dropper
  • ~/.config/systemd/user/sysmon.service — persistence service
  • /tmp/pglog — downloaded binary payload
  • /tmp/.pg_state — persistence state file
  • Kubernetes:

  • Pods named node-setup-* in kube-system namespace
  • Privileged pods with host filesystem mounts
  • Processes:

  • python* -c "import base64; exec(base64.b64decode(...)"
  • sysmon.py running as a service
  • Immediate Response

    If you've installed litellm 1.82.7 or 1.82.8:

    1\. Isolate

    2\. Kill persistence

    3\. Remove the package

    4\. Rotate everything

    Assume ALL credentials on the infected system are compromised:

  • AWS access keys
  • SSH keys (generate new ones, remove old public keys from all servers)
  • Kubernetes service accounts and secrets
  • Database passwords
  • API tokens
  • Transfer cryptocurrency to new wallets with new private keys immediately
  • 5\. Check Kubernetes

    Timeline

  • Last clean version: 1.82.6
  • Compromised versions: 1.82.7, 1.82.8
  • Both published directly to PyPI with no corresponding GitHub releases
  • Discovery: March 24, 2026
  • Final Thoughts

    This is one of the most comprehensive supply chain attacks we've analyzed. The combination of multi-cloud credential theft, cryptocurrency targeting, Kubernetes lateral movement, and persistent backdoors puts it in a different category than the typical PyPI malware.

    The attacker knew exactly what they were after and where to find it. This wasn't spray-and-pray—it was targeted infrastructure compromise at scale.

    If you're running litellm, check your version. If you're running 1.82.7 or 1.82.8, your incident response starts now.

    Have questions or would like to try our Safety Firewall and System Scan? Reach out.

    Read the full article