大型語言模型閘道工具 LiteLLM 在 10 月 21 日遭遇供應鏈投毒。雲端資安公司 Wiz 揭露,遭竄改的 LiteLLM 1.107.0 當天在 PyPI 上架,GHCR 與 Docker Hub 上標有 v1.107.0、latest、main-latest、main-stable 標籤的映像檔也被植入了同一套竊密程式。官方給出的最近一個安全版本是 v1.106.2。
LiteLLM 由 BerriAI 開發,常見用法是在企業內部架一層代理,透過統一介面轉發到 OpenAI、Anthropic、Bedrock 等上百個模型服務。代理背後存放著各家廠商的 API 金鑰,這次攻擊瞄準的正是這一點。
一安裝就開始偷
惡意套件會在 site-packages 根目錄放入三個檔案:cook.pth、cook.py 與 sitecustomize.py。前兩者借助 Python 的 .pth 機制,只要直譯器啟動就會執行,業務程式碼不需要 import LiteLLM。
竊密程式內部名稱為 privcollect,共有 16 個模組,鎖定的目標包括:
- Chrome、Firefox、Edge、Safari 的瀏覽器憑證與 Cookie
- AWS、GCP、Azure 的雲端憑證
- OpenAI、Anthropic、Cohere 等 AI 廠商的 API 金鑰
- SSH、GPG 私鑰與 shell 歷史紀錄
- 直接從 LiteLLM Proxy 的 PostgreSQL 資料庫查出的上游廠商憑證
資料先以 AES-256-CBC 加密,金鑰再用 RSA-4096 包一層,透過 HTTP POST 傳送到攻擊者註冊的仿冒網域 www.litellm[.]dev。sitecustomize.py 只會在 Linux 與 macOS 上執行,會到 GitHub 上一個「死信箱」儲存庫取得第二階段位址;Wiz 表示這個檔案除了測試值之外一直沒有填入內容,GitHub 已刪除該儲存庫。
把時間線攤開
依 Wiz 公布的 UTC 時間粗略換算各個時間窗:
| 環節 | 時間(UTC) | 持續時間 |
|---|---|---|
| 仿冒儲存庫推送 10 次提交 | 08:56–10:46 | 約 1 小時 50 分鐘 |
| PyPI 惡意版本在線 | 11:39–13:20 | 約 1 小時 41 分鐘 |
| Docker 遭竄改標籤在線 | 約 13:53 前後下架 | 從 PyPI 上架起算約 2 小時 14 分鐘 |
| 攻擊者驗證 AWS 憑證 | 16:20–17:01 | 距外傳約 4.5 小時 |
PyPI 上那一個多小時看起來不長,但 latest 這類標籤會被大量 CI 流水線和 Kubernetes 部署自動拉取,暴露面主要取決於這段時間內有多少環境重建過映像檔。Wiz 沒有提供下載量,受影響的組織數量目前也無法查證。
攻擊者取得憑證後,利用遭入侵的 CI runner 與 Kubernetes 節點上的 AWS 執行個體角色,呼叫了 sts:GetCallerIdentity、bedrock:ListFoundationModels 等介面。Wiz 認為這與 LLMjacking 的手法一致,也就是盜用他人的雲端帳號白嫖大型語言模型呼叫;在部分環境裡,攻擊者還列舉了 IAM 作為例行偵察。
入口懷疑是 GitHub 權杖
攻擊者推送的那 10 次提交落在仿冒儲存庫 Berri-AI/litellm,前 9 次帶有 GitHub 簽章,最後一次沒有簽章,電子郵件信箱也換了。BerriAI 方面的說法是:
"malicious actions were taken through three engineers' GitHub accounts"
(惡意操作是透過三名工程師的 GitHub 帳號完成的。)
LiteLLM 懷疑這幾枚 GitHub CLI OAuth 權杖是從一個暴露在公網的內部部署環境洩漏出來的,可能與一個剛修補的漏洞有關,Wiz 明確寫出這一點尚未證實。BerriAI 表示涉事權杖已全數撤銷。使用過 1.107.0,或在那段時間拉取過上述映像檔的團隊,需要把機器上讀得到的雲端憑證、模型金鑰與 SSH 私鑰全部輪替一遍。
參考來源:Wiz 研究部落格、CocoLoop、Wiz 威脅情報中心通告、BerriAI 公開聲明;已查核受影響版本與映像檔標籤、惡意檔名及各環節 UTC 時間。