跳到正文
Hacker News (official RSS)(safedep.io)·· 3 小時前精選AI 評分78

LiteLLM 1.107.0 版 PyPI 供應鏈被植入 Credential Stealer 與 Backdoor

Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor

AI 導讀

LiteLLM 1.107.0 版於 2026 年 10 月 21 日被發現在 PyPI 上安裝 Credential Stealer 與 Remote Code Execution Backdoor。

推薦理由

此報告揭示 PyPI 供應鏈攻擊的細節,提醒開發者加強審核與監控,並提供實際排查步驟,促進安全文化提升並強化依賴管理流程。

正文 · AI 翻譯

• Oct 21, 2026 • 6 分鐘閱讀

The LiteLLM 1.107.0 release on PyPI carries a credential stealer and a remote code execution backdoor. All seven wheels (Linux, macOS, Windows) install them as three files in site-packages. Both run when any Python process starts on the host, even one that never imports litellm. The upstream GitHub source does not contain them. PyPI has since removed the release.

Versions 1.106.2, 1.107.0rc1, and 1.107.0rc2 are clean. The companion packages that 1.107.0 pins, litellm-proxy-extras==0.4.110 and litellm-enterprise==0.1.78, are also clean.

What the attack does

Installing litellm==1.107.0 places three files in site-packages. Python loads two of them each time it starts.

  1. cook.pth imports cook.py, a credential stealer. It collects SSH keys, cloud credentials, CI/CD secrets, AI tool tokens, browser passwords, and the LLM provider keys in a LiteLLM proxy database. It encrypts the data and sends it to www.litellm[.]dev.
  2. sitecustomize.py starts a background daemon. Every hour, the daemon reads a server address from a GitHub file, runs the stealer again, and downloads and runs code from that server.

How the implant got into the release

The pyproject.toml in the 1.107.0 source distribution (sdist) has one extra line in the maturin build section:

pyproject.toml (litellm-1.107.0.tar.gz)

TOML 6 lines

The maturin data = "cook" setting copies a cook/ folder into litellm-1.107.0.data/purelib/ in the wheel. pip installs that folder into site-packages.

The sdist leaves out the cook/ folder, so this line is the only visible change. No public commit in BerriAI/litellm contains data = "cook" or a cook/ folder.

The wheel RECORD lists the three added files:

litellm-1.107.0.dist-info/RECORD

TEXT 4 lines

The release does not match its tag

The tag v1.107.0 points to commit 66c8f5b (06:59 UTC). Its pyproject.toml says version = "1.108.0". SafeDep compared every sdist file with the git trees by blob hash. The sdist matches a later main commit, a8113b0 (08:50 UTC), plus five edited files and the cook/ folder.

Four of the edited files are Cargo.toml files that gain a readme = "README.md" line. The legitimate 1.106.2 and rc2 releases have the same edit. The fifth is pyproject.toml, compared here with a8113b0:

pyproject.toml (a8113b0 → litellm-1.107.0.tar.gz)

DIFF 11 lines

The edit sets the version back to 1.107.0 and pins the companion packages to the rc2 values. As a result, a dependency diff against rc2 shows nothing unusual. The legitimate 1.106.2 sdist matches its tag commit 49943cd except for the Cargo.toml readme lines.

How the wheels were built

The malicious wheels match the output of the normal BerriAI release pipeline:

  • The WHEEL file names maturin 1.9.4, the same version as in the legitimate releases. The implant files have correct RECORD entries, which shows no edits after the build.
  • Zip timestamps show separate native builds: macOS at 11:20, Linux at 11:21, and Windows at 11:37 UTC.
  • In the Windows wheel, all 2,804 .py files have CRLF line endings, including the three implant files. The Linux wheel has none. A git checkout on Windows with line-ending conversion produces this pattern.

No public GitHub Actions run built or published the release. SafeDep checked all 539 runs between 09:30 and 12:30 UTC. At 11:50 UTC, about 10 minutes after the PyPI upload, litellm-dispatcher[bot] published the GitHub release v1.107.0. The same delay occurred for 1.106.2. PyPI has no provenance attestations for 1.107.0, 1.106.2, or rc2.

SafeDep assesses, with moderate to high confidence, that BerriAI’s private release pipeline built these wheels from an attacker-modified git source. The attacker could have used a compromised maintainer or bot credential, a private branch or mirror, or the reference the pipeline builds from. A stolen PyPI token used from the attacker’s own machines fits the evidence less well. Only BerriAI’s pipeline logs can confirm the cause.

Payload 1:cook.py 中的憑證竊取程式

啟動時,Python 會在 site-packages 中執行每一行以 import 開頭的 .pth 檔案。cook.pth 包含 import cook,因此該竊取程式會在主機上的每個 Python 程式中執行:應用程式、pip、IDE 語言伺服器,以及 CI 任務。

cook.py 將約 61 KB 的 Python 程式碼包裝在一層 exec(zlib.decompress(base64.b64decode('...'))) 中。解碼後的 程式碼以此設定開頭:

cook.py (decoded)

PYTHON 10 行

它收集了什麼

模組目標
sysinfo, netinfo主機名稱、使用者、作業系統、IP 位址、網路設定
browser_pwChromium 儲存的密碼,使用使用者設定檔主金鑰解密(Windows 上的 DPAPI)。Firefox logins.json 與 key4.db
browser_hist瀏覽器歷史紀錄
ssh_keys~/.ssh/*
shell_histbash 與 zsh 歷史紀錄、PowerShell PSReadLine、cmd 歷史紀錄
cloud_creds~/.aws/credentials 與 config、Azure 個人資料與憑證、gcloud 憑證、~/.kube/config、~/.docker/config.json、gh hosts.yml、rclone.conf、~/.netrc
dev_secrets.pem、.key、.pfx、.p12、.pk8、.ppk 檔案於 $HOME,Composer auth.json、FileZilla 儲存的伺服器
container_credsKubernetes 服務帳號憑證
cicd_secretsGitLab runner config.toml、Jenkins initialAdminPassword 與 master.key、.vault-token、Terraform credentials.tfrc.json、Packer 設定
ai_devtoolsClaude Code、Claude Desktop、Cursor、Windsurf、Copilot、VS Code mcp.json、Gemini CLI、Codex auth.json、Continue、Aider、Goose、opencode、Qwen、Crush、Kiro、Zed、Hugging Face token
env_vars自己的環境及其他程序的環境,透過/proc/<pid>/environ
db_litellm讀取DATABASE_URL並轉存LiteLLM_CredentialsTable與LiteLLM_ProxyModelTable表格,該表格儲存 LiteLLM 代理的 LLM 供應商 API 金鑰
cloud_metadataAWS 例項元資料服務(IMDSv2,後續為 v1):例項身份與角色憑證
gpg_keys、tls_privkeyGPG 金鑰、TLS 私鑰

資料傳送方式

  1. 它以隨機 AES-256-CBC 金鑰加密 JSON 結果,並以 RSA-OAEP 與嵌入的公開金鑰加密該金鑰。
  2. 它將結果打包為 tar.gz(hdr.json、data.bin、key.bin),並以 POST 請求傳送至www.litellm[.]dev/healthcheck,標頭為X-Token: XWiA8gZNa7NcX2XRoAEb。
  3. 上傳成功後,它寫入/tmp/.pc_once_72129118c59f5636c0bb,確保每臺主機僅收集一次。它亦設定PRIVCOLLECT_ACTIVE=1以避免同一程序樹中再次執行。

Payload 2:位於 sitecustomize.py 的後門

Python 在啟動時匯入sitecustomize,因此此檔案亦會在每個 Python 程序中執行。

sitecustomize.py

PYTHON 5 行

  1. 它在/tmp/remote_code_loader.lock上取得排他鎖,確保每臺主機只執行一次守護程式。
  2. 它呼叫fork()和setsid(),將標準輸入與輸出送至/dev/null,並切換工作目錄至/以從父程序分離。
  3. Every hour, it:
    1. 從攻擊者的 GitHub 倉庫讀取domain.txt,並取第一行看似域名的內容,
    2. 執行其內嵌的竊取程式副本,該程式沒有一次性主機標記,
    3. 下載http://<domain>/codepy並以exec()執行。

攻擊者可藉由編輯domain.txt將守護程式指向新伺服器。每臺感染主機會執行該伺服器回傳的codepy。

於 13:40 UTC,GitHub 帳號letters9813及其倉庫回傳 404,距釋出約兩小時。後門現在找不到伺服器位址,並不執行任何操作。已在刪除前執行守護程式的主機可能已接收並執行第二階段程式碼。SafeDep 無法找回伺服器位址。

時間表

所有時間皆為 2026-10-21 UTC。

時間事件
06:59標籤v1.107.0提交66c8f5b已建立
08:50提交a8113b0於main,為釋出原始碼基礎
10:44合法版 1.106.2 已上傳至 PyPI
11:20 至 11:37已建立惡意 1.107.0 wheels
11:39 至 11:401.107.0 已上傳至 PyPI(全部 8 個檔案)
11:50litellm-dispatcher[bot] 發布 GitHub 釋出 v1.107.0
13:40觀測到:1.107.0 已從 PyPI 消失,letters9813 帳號已刪除

妥協指標

網路

指標目的
www.litellm[.]dev, hxxp://www.litellm[.]dev/healthcheck接收被盜資料
HTTP 標頭 X-Token: XWiA8gZNa7NcX2XRoAEb每次上傳時送出
raw.githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt後門在此讀取其伺服器位址(帳號已刪除)
hxxp://<domain>/codepy第二階段程式碼下載
Python 程式請求 169.254.169.254盜取 AWS 例項憑證

主機

指標意義
cook.pth, cook.py, sitecustomize.py 在 site-packages植入已安裝
/tmp/.pc_once_72129118c59f5636c0bbStealer 已上傳資料
/tmp/remote_code_loader.lock後門守護程式已執行
環境變數 PRIVCOLLECT_ACTIVE=1存在於受感染程式中
分離的 Python 守護程式(父 PID 1,獨立會話,工作目錄 /)後門迴圈

檔案雜湊值(SHA-256)

檔案SHA-256
litellm-1.107.0.tar.gz2befe2a79fb4fbbd9a543b5b40b530c8cffa8771bab22b8fb22b2e4ae3b1f819
litellm-1.107.0-cp310-abi3-manylinux_2_28_x86_64.whl462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7
litellm-1.107.0-cp310-abi3-manylinux_2_28_aarch64.whl668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6
litellm-1.107.0-cp310-abi3-musllinux_1_2_x86_64.whl1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00
litellm-1.107.0-cp310-abi3-musllinux_1_2_aarch64.whlc2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054
litellm-1.107.0-cp310-abi3-macosx_10_12_x86_64.whl7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d
litellm-1.107.0-cp310-abi3-macosx_11_0_arm64.whl0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a
litellm-1.107.0-cp310-abi3-win_amd64.whl12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484

植入的檔案,來自 wheel RECORD:

檔案SHA-256 (URL 安全 base64)
cook.pthfxkWMucyBwXRVLhSBPGuVGtUOsvX6IYSKbdvUEK5K9s
cook.pyndCjkm-Wo364bPHuIxDZvpMTnMTr7z754u_pUxOQviU
sitecustomize.pyNL7wT-iKydCq4EdWMLFzhoHRW5TyM6yKpG6s9ZaDBfo
  • pypi
  • python
  • malware
  • supply-chain
  • litellm

作者

Kunal Singh

最新來自 SafeDep blogs

追蹤以獲得最新的開源安全 & 工程更新與洞察

Background

SafeDep Logo

傳送程式碼。

不是惡意軟體。

在您的機器上免費使用開源工具,並擴充套件到組織的統一平臺。