5 phút đọc

LiteLLM 1.107.0 chứa mã độc, chỉ cần mở Python là key bị gửi đi

Bản LiteLLM 1.107.0 trên PyPI và Docker bị cài mã độc lấy key cloud, key AI, mật khẩu trình duyệt. Ai cài hay kéo image trong chiều tối 21/10 (giờ Việt Nam) cần dựng lại môi trường bằng 1.106.2 và đổi mọi khóa.

Xem nhanh trong 1 phút

Kẻ tấn công vào được quy trình phát hành của LiteLLM nhờ token GitHub nằm trong file log. Token đó lọt vào log vì một con gateway LiteLLM nội bộ ghi lại nguyên văn câu trả lời của AI, và câu trả lời có chứa token.

Kết quả là bản LiteLLM 1.107.0 phát hành ngày 21/10 mang theo mã độc. LiteLLM là thư viện Python để gọi hàng trăm model AI qua một giao diện chung, đồng thời là proxy giữ key OpenAI, Anthropic cho cả team. BleepingComputer ghi nhận gói này có khoảng 92 triệu lượt tải mỗi tháng trên PyPI.

Linh vật robot mở hộp gói hàng, ba mảnh giấy đỏ bay ra kéo theo chìa khóa về phía khe nứt trên tường, cạnh đó là cuốn sổ kẹp chìa khóa

Ai bị dính

Theo thông báo của BerriAI, công ty làm LiteLLM, bạn bị ảnh hưởng nếu:

  • Cài litellm không ghim phiên bản trong khoảng 11:39 đến 13:23 UTC ngày 21/10, tức 18:39 đến 20:23 giờ Việt Nam. Cả bảy file wheel (macOS, Linux, Windows) đều nhiễm.
  • Kéo image Docker tag v1.107.0, latest, main-latest hoặc main-stable trong khoảng 11:46 đến 14:20 UTC (18:46 đến 21:20 giờ Việt Nam). Gồm litellm/litellm trên Docker Hub và ghcr.io/berriai/litellm, litellm-database, litellm-non_root trên GHCR.

Thời gian ngắn, nhưng CI chạy đêm, server tự kéo latest khi khởi động lại thì vẫn trúng. Bản 1.106.2 trở về trước không bị gì. Khách dùng bản enterprise riêng cũng không bị ảnh hưởng.

Mã độc làm gì

Mã nguồn của LiteLLM không bị sửa. Hacker chỉ nhét thêm ba file vào gói cài: cook.pth, cook.py và sitecustomize.py.

Chỗ khó chịu nằm ở file .pth. Python tự đọc các file này mỗi lần trình thông dịch khởi động, nên bạn không cần import litellm. Chạy một script bất kỳ, chạy pip, mở REPL trong môi trường đó là mã độc chạy.

Theo phân tích của StepSecurity, cook.py gom gần như mọi thứ có giá trị trên máy:

  • Key AWS, Azure, GCP, kubeconfig, token GitHub CLI, .npmrc, .pypirc, file .env trong thư mục làm việc
  • Khóa SSH, GPG, mật khẩu và cookie lưu trong Chrome, Edge, Brave, Firefox
  • Cấu hình và token của công cụ code AI: Claude Code, Cursor, Windsurf, Copilot, Cline, Codex, Gemini CLI, cùng file cấu hình MCP trong VS Code
  • Biến môi trường của mọi tiến trình đọc được trên máy Linux
  • Với image litellm-database, nó đọc thẳng bảng chứa key của các nhà cung cấp AI trong database của proxy

Dữ liệu được mã hóa rồi gửi tới litellm.dev, một tên miền giả đăng ký từ 13/10. File còn lại, sitecustomize.py, chạy ngầm và cứ mỗi giờ hỏi một địa chỉ trên GitHub xem có mã mới để tải về chạy không. StepSecurity cho biết lúc phát hành, địa chỉ đó đang để trống, nên phần tải mã về chưa kích hoạt. Phần lấy key thì đã chạy.

Hacker vào bằng cách nào

Theo báo cáo của BerriAI, kẻ tấn công vào được một bản LiteLLM triển khai nội bộ nhưng lại mở ra internet. Vào bằng lỗ nào thì công ty chưa xác nhận, chỉ nghi là một lỗ hổng vừa được vá. Trong log của bản này có token GitHub CLI của ba lập trình viên. BerriAI giải thích rằng trong một số tình huống, Claude Code đưa token GitHub CLI vào nội dung câu trả lời, và gateway lại được cấu hình ghi log cả nội dung câu trả lời.

Có ba token, hacker dùng token của một chủ tổ chức GitHub để gỡ chế độ bảo vệ nhánh, sửa workflow phát hành cho nó build từ repo giả Berri-AI/litellm (thêm dấu gạch nối). Token thứ hai dùng để bấm duyệt bước phát hành. Token thứ ba xóa lịch sử chạy workflow. Cả quá trình mất chưa tới hai tiếng.

Đây là lần thứ hai trong năm LiteLLM bị đầu độc. Sau vụ tháng 3, họ đã chuyển việc phát hành sang repo riêng, dùng Trusted Publisher, ký image. Những lớp đó vẫn bị vượt vì token thật nằm trong tay hacker.

Mình thấy bài học lớn nhất ở đây không nằm ở PyPI. Nó nằm ở file log. Nhiều người dựng proxy AI cho team, bật ghi log đầy đủ để tiện xem lại prompt, mà quên rằng prompt và câu trả lời của agent code thường chứa token, nội dung .env, chuỗi kết nối database.

Nếu bạn có dùng LiteLLM

  1. Đừng chạy pip hay python trong môi trường nghi nhiễm. Làm vậy là chạy luôn mã độc. Kiểm tra bằng shell:

    find / -path "*site-packages*" -name cook.pth 2>/dev/null
    ls -la /tmp/.pc_once_* /tmp/remote_code_loader.lock
    docker images --digests | grep -E 'berriai/litellm|litellm/litellm'

    File /tmp/.pc_once_... có nghĩa là dữ liệu đã gửi đi. Không thấy file này cũng chưa chắc an toàn.

  2. Dừng tiến trình chạy ngầm đang giữ /tmp/remote_code_loader.lock (xem bằng lsof).

  3. Dựng lại môi trường từ đầu: xóa virtualenv, build lại image, cài litellm==1.106.2. Với Docker, ghim theo digest thay vì tag. Xóa image 1.107.0 trong registry nội bộ và cache.

  4. Coi như mọi khóa trên máy đó đã lộ nếu máy có ra internet: key cloud và IAM role, khóa SSH, token GitHub, npm, PyPI, key AI, mật khẩu lưu trong trình duyệt. Trên máy chạy proxy, đổi cả key của từng nhà cung cấp trong database, master key, virtual key và mật khẩu DATABASE_URL.

  5. Xem log mạng có truy cập litellm.dev không, và trên AWS CloudTrail xem có lệnh GetCallerIdentity lạ quanh lúc cài.

Không dính vụ này thì vẫn nên làm hai việc: ghim phiên bản trong requirements.txt hay file lock thay vì để trống, và mở cấu hình log của proxy AI xem nó có đang lưu nguyên văn prompt và câu trả lời không.


Team bạn có tự dựng proxy AI như LiteLLM không, và log của nó đang lưu những gì? Vào cộng đồng Vibe Code & Bảo Mật kể cho mọi người nghe nhé.

Nguồn

Chia sẻ lên Facebook

Bình luận

Đang tải bình luận…