Trojanized LiteLLM 1.107.0 Package Steals Credentials Through Python Startup Hooks

· Original article ↗

Summary

A trojanized LiteLLM 1.107.0 package and Docker images stole credentials via Python startup hooks. The stealer targeted cloud, browser, AI and other secrets; the malicious release and images were removed, and involved tokens revoked.

Key points

  • The malicious LiteLLM 1.107.0 package was uploaded to PyPI on October 21; trojanized Docker images also carried it. PyPI quarantined the package, and the affected image tags were removed.
  • The attacker reportedly used stolen GitHub CLI OAuth tokens from three engineers’ accounts to push malicious commits and trigger and approve the release. BerriAI said the involved tokens were revoked.
  • The package used cook.pth to load cook.py at Python interpreter startup; a second startup script, sitecustomize.py, attempted to retrieve a follow-on payload through a GitHub-hosted dead drop.
  • The stealer collected browser, cloud, SSH, GPG, shell-history and AI-provider credentials, and queried LiteLLM Proxy’s PostgreSQL credentials table.
  • Harvested data was encrypted and sent to an attacker-controlled lookalike domain, litellm[.]dev. The article says the second-stage domain file had not been populated beyond test values at analysis time.
  • The article identifies 1.106.2 as the latest safe version and provides hashes for affected package wheels and container images.

Article Details

Attack Vectors
  • A malicious LiteLLM 1.107.0 package was uploaded to PyPI and included in LiteLLM Docker images; startup-executed cook.pth and sitecustomize.py files enabled credential theft and loader behavior.
  • The attacker reportedly used stolen GitHub CLI OAuth tokens to access engineers' GitHub accounts, push malicious commits, and trigger and approve the project release.
  • The stealer harvested browser credentials and cookies, cloud credentials and tokens, AI-provider API keys, SSH and GPG keys, shell history, and credentials stored in the LiteLLM Proxy PostgreSQL database.
  • Stolen data was encrypted and sent by HTTP POST to an attacker-controlled lookalike LiteLLM domain. A separate sitecustomize.py loader attempted to retrieve a second-stage script via a GitHub dead-drop file.
Defensive Notes
  • The malicious 1.107.0 package was quarantined on PyPI; the article identifies 1.106.2 as the most recent safe version.
  • The trojanized Docker tags v1.107.0, latest, main-latest, and main-stable were removed, and the GitHub repository used for the dead drop was taken down.
  • LiteLLM's developer reported that all tokens involved in the attack had been revoked.
  • Review the article's SHA-256 indicators for affected package wheels and container images, and its listed hashes for cook.pth, cook.py, and sitecustomize.py.

Indicators of compromise

TypeIndicatorContext
DOMAINlitellm[.]devAttacker-controlled lookalike domain identified as exfiltration infrastructure.
EMAILckdi82fkoos@proton[.]meAuthor email used for the attacker's malicious commits.
SHA25603ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897eaHash of the Windows cook.py credential-stealer payload.
SHA2560aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1aHash of the malicious LiteLLM 1.107.0 macOS arm64 wheel.
SHA25612d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484Hash of the malicious LiteLLM 1.107.0 Windows wheel.
SHA2561bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00Hash of the malicious LiteLLM 1.107.0 musllinux x86_64 wheel.
SHA25624581ddc30767f16ecb69d2b0517556f2cd7dea56971adb42a3d1beb97d69523Hash of the trojanized LiteLLM database container image for linux/amd64.
SHA25634bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305faHash of the Linux/macOS sitecustomize.py loader.
SHA256462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7Hash of the malicious LiteLLM 1.107.0 manylinux x86_64 wheel.
SHA25656b74573eed6e4aafe4b50603dbe7853e0345f188c8e44a09f1098caf1f4bcdfHash of the trojanized LiteLLM 1.107.0 GHCR and Docker Hub linux/arm64 image.
SHA256645a67d810628252d63df85dcc8824c58bcc77cf8383f4d3e6321f0ccc3ce9e4Hash of the trojanized LiteLLM non-root container image for linux/amd64.
SHA256668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6Hash of the malicious LiteLLM 1.107.0 manylinux aarch64 wheel.
SHA2567598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86dHash of the malicious LiteLLM 1.107.0 macOS x86_64 wheel.
SHA2567f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdbHash of the cook.pth persistence hook for Linux and macOS.
SHA256827dd893c74cf621a860a66a3a447a5c732533f087589ce905573e285c0a239cHash of the trojanized LiteLLM database container image for linux/arm64.
SHA25684dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7dHash of the cook.pth persistence hook for Windows.
SHA2569dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25Hash of the Linux/macOS cook.py credential-stealer payload.
SHA256b6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465Hash of the Windows sitecustomize.py loader.
SHA256bd1aeee419ea36da9aa2b657288da4101887be468f020ac63d22ba6ed84a3ea5Hash of the trojanized LiteLLM 1.107.0 GHCR and Docker Hub linux/amd64 image.
SHA256c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054Hash of the malicious LiteLLM 1.107.0 musllinux aarch64 wheel.
SHA256f75c8edae59b72b1ebfd617295833f465c85bb2fab9c1d60f21b496db86cb8daHash of the trojanized LiteLLM non-root container image for linux/arm64.

MITRE ATT&CK

T1005 · Data from Local SystemThe stealer gathered local files including cloud and AI configuration data, keys, and shell history.T1027 · Obfuscated Files or Informationcook.py deobfuscated itself before running its credential-stealing routine.T1041 · Exfiltration Over C2 ChannelThe malware sent encrypted stolen data to its attacker-controlled endpoint.T1059.006 · PythonPython startup files cook.pth and sitecustomize.py caused malicious Python code to execute when an interpreter started.T1071.001 · Web ProtocolsStolen data was exfiltrated over HTTP POST to the attacker-controlled healthcheck endpoint.T1102.001 · Dead Drop Resolversitecustomize.py attempted to retrieve domain.txt from a GitHub repository used as a dead drop.T1105 · Ingress Tool TransferThe loader attempted to download and run a second-stage Python script from the domain specified by the dead-drop file.T1195.002 · Compromise Software Supply ChainThe attacker inserted malicious files into the LiteLLM release pipeline and distributed them through the PyPI package and Docker images.T1528 · Steal Application Access TokenThe stealer targeted Azure CLI cached tokens.T1550.001 · Application Access TokenAccording to LiteLLM's developer, the attacker appeared to use stolen GitHub CLI OAuth tokens to operate through engineers' GitHub accounts.T1552.001 · Credentials In FilesThe stealer searched ~/.aws/ and environment variables for AWS credentials.T1552.004 · Private KeysThe stealer collected SSH private keys and GPG keys.T1552.006 · Group Policy PreferencesThe stealer queried EC2/ECS instance metadata for credentials.T1555 · Credentials from Password StoresThe stealer collected credentials and cookies from Chrome, Firefox, Edge, and Safari.T1555.003 · Credentials from Web BrowsersThe payload targeted browser credentials and cookies stored by Chrome, Firefox, Edge, and Safari.

Malware

Vendors

Products

Related Articles