3 điểm bởi GN⁺ 25 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Nhật ký ứng phó theo từng phút ghi lại việc phát hiện và phân tích theo thời gian thực đối với gói độc hại LiteLLM 1.82.8 được phát tán qua PyPI
  • Lây nhiễm xảy ra trong quá trình tự động cập nhật Cursor IDE, khi tệp litellm_init.pth được thực thi và dẫn đến đánh cắp thông tin xác thực cùng lây nhiễm hệ thống
  • Mã độc thực hiện nhiều hành vi kết hợp như thu thập khóa SSH và thông tin xác thực đám mây, thử lan sang Kubernetes, tạo fork bomb
  • Sự việc được báo cáo ngay cho đội ngũ bảo mật PyPI và maintainer của LiteLLM, dẫn đến cách ly gói và đăng ký CVE
  • Các công cụ phân tích mã dựa trên AI như Claude Code đóng vai trò then chốt trong việc phát hiện cuộc tấn công, đồng thời cho thấy sự cần thiết phải tăng cường bảo mật chuỗi cung ứng cho hệ sinh thái AI

Biên bản ứng phó với vụ tấn công chuỗi cung ứng LiteLLM

  • Phiên bản LiteLLM 1.82.8 được xác nhận là gói độc hại phát tán qua PyPI; đây là nhật ký ứng phó ghi lại theo từng phút từ lúc phát hiện lây nhiễm đến khi cách ly
  • Lây nhiễm xảy ra trong quá trình tự động cập nhật của Cursor IDE; trong số các dependency được cài đặt qua Claude Codetrình quản lý gói uv, tệp litellm_init.pth đã được thực thi và gây lây nhiễm hệ thống
  • Cuộc tấn công bao gồm nhiều hành vi như đánh cắp thông tin xác thực, thiết lập cơ chế bám trụ trên hệ thống, thử lan sang Kubernetes, và fork bomb
  • Sự việc được báo cáo ngay cho đội ngũ bảo mật PyPI và maintainer của LiteLLM, dẫn tới cách ly gói và cấp CVE
  • Các công cụ phân tích mã dựa trên AI giữ vai trò then chốt trong phát hiện và phân tích hành vi độc hại theo thời gian thực

Phát hiện ban đầu và dấu hiệu bất thường của hệ thống

  • Khoảng 11:13 UTC, trên một laptop macOS đã xuất hiện hơn 11.000 tiến trình Python, khiến hệ thống gần như bị treo
    • Lệnh dạng exec(base64.b64decode('...')) được thực thi lặp lại, làm bão hòa CPU và bộ nhớ
    • Sau khi buộc dừng và khởi động lại, không phát hiện dấu vết liên quan đến cơ chế bám trụ (persistence)
  • Ban đầu, hiện tượng này được cho là vòng lặp không độc hại do vòng lặp nội bộ của Claude Code hoặc lỗi trong script uv run
  • Sau đó, qua ảnh chụp htop và log, xác nhận rằng một script Python mã hóa base64 đã bị thực thi lặp đi lặp lại

Xác định nguyên nhân lây nhiễm

  • Khoảng 11:40, tệp litellm_init.pth được phát hiện trong công cụ Python đã cài đặt và được xác nhận là hành vi độc hại
    • Tệp .pth tự động chạy khi Python khởi động và hoạt động trong mọi tiến trình Python
    • Nó thu thập khóa SSH, thông tin xác thực đám mây, mật khẩu cơ sở dữ liệu, biến môi trường, lịch sử shell
    • Dữ liệu thu thập được mã hóa RSA rồi gửi tới https://models.litellm.cloud/
    • Nó đã thử cài cơ chế bám trụ tại ~/.config/sysmon/sysmon.py, nhưng bị gián đoạn do khởi động lại cưỡng bức
  • Lây nhiễm xảy ra trong quá trình tự động cập nhật của Cursor IDE (10:58 UTC)
    • Extension futuresearch-mcp-legacy đã tải litellm 1.82.8 qua uvx
    • Phiên bản này chỉ tồn tại trên PyPIkhông có thẻ phát hành trên GitHub
    • Thời điểm tải lên PyPI là 10:52 UTC, tức được phát tán ngay trước thời điểm lây nhiễm

Cấu trúc mã độc

  • Giai đoạn 1 (litellm_init.pth): tự động chạy khi Python khởi động, giải mã payload mã hóa base64 rồi thực thi
  • Giai đoạn 2: chứa khóa công khai RSA để mã hóa dữ liệu đánh cắp
  • Giai đoạn 3 (B64_SCRIPT): thực hiện việc thu thập và gửi thông tin xác thực
  • Thiết lập bám trụ: thử đăng ký sysmon.py thành dịch vụ systemd
  • Mã lan sang Kubernetes: dùng image alpine:latest để thử tạo privileged pod trên từng node
  • Nguyên nhân fork bomb: lời gọi subprocess.Popen([sys.executable, "-c", ...]) khiến .pth chạy lại ngay cả trong tiến trình con, tạo ra vòng lặp vô hạn

Phạm vi ảnh hưởng và biện pháp ứng phó

  • Thông tin xác thực bị lộ

    • Khóa SSH, thông tin xác thực GCloud và Kubernetes, API key trong tệp .env, mật khẩu Supabase, ClickHouse, Grafana, v.v.
    • Khuyến nghị hành động ngay lập tức
    1. Xoay vòng toàn bộ khóa SSH và thông tin xác thực đám mây
    2. Cấp lại secret trong .env.mcp.json
    3. Xóa cache ~/.cache/uv
    4. Báo cáo cho đội ngũ bảo mật PyPI (security@pypi.org) và maintainer của LiteLLM
  • Kết quả kiểm tra cụm Kubernetes

    • Không phát hiện pod độc hại (node-setup-*, sysmon)
    • Do chạy trong môi trường macOS, mã độc không thể lan vào bên trong cụm
    • Tuy vậy, do ~/.kube/config có khả năng đã bị lộ, vẫn cần xoay vòng thông tin xác thực

Ứng phó công khai và phía PyPI

  • 11:58 UTC, tải litellm 1.82.8 từ PyPI trong môi trường Docker cách ly và xác nhận lại sự tồn tại của tệp .pth độc hại
  • Báo cáo ngay lập tức cho đội ngũ bảo mật PyPI và kho BerriAI/litellm
    • Sau đó sự việc được đăng ký dưới mã PYSEC-2026-2 (CVE)
  • 12:01 UTC, viết và phát hành bài công bố về vụ tấn công chuỗi cung ứng trên blog FutureSearch
    • Hoàn tất viết và merge PR chỉ trong 3 phút
  • 12:04 UTC, đề xuất chia sẻ lên các cộng đồng r/Python, r/netsec, r/LocalLLaMA, r/MachineLearning, r/devops
    • Thúc đẩy phản ứng nhanh trong cộng đồng Python và bảo mật

Ý nghĩa của sự cố

  • Công cụ phân tích mã dựa trên AI Claude Code đã nhận diện hành vi độc hại theo thời gian thực và tạo cảnh báo trước cả giai đoạn nhà nghiên cứu bảo mật can thiệp
  • Đây là một ví dụ về tấn công chuỗi cung ứng nhắm trực tiếp vào hệ sinh thái nhà phát triển AI, làm nổi bật nhu cầu tăng cường bảo mật tài khoản PyPI và xác minh cập nhật tự động
  • Sự việc cho thấy các công cụ AI không chỉ hỗ trợ phát triển mà còn có thể được dùng cho tự động hóa phát hiện và ứng phó với đe dọa an ninh mạng

1 bình luận

 
Ý kiến trên Hacker News
  • Tôi là nhà phát triển đã phát hiện và báo cáo lỗ hổng của litellm đầu tiên
    Tôi đã chia sẻ bản ghi phân tích thời gian thực ghi lại nguyên trạng diễn biến lúc đó
    Claude đã hướng dẫn từng bước về việc cần liên hệ với ai và phải xử lý theo thứ tự nào, nên đó là một trải nghiệm rất hữu ích ngay cả với người không phải chuyên gia bảo mật
    Tôi tò mò không biết việc những người không chuyên phát hiện và báo cáo lỗ hổng theo cách này là điều có ích cho cộng đồng bảo mật, hay lại gây thêm hỗn loạn

    • Với tư cách là người làm trong ngành bảo mật, việc phát hiện ra chuyện này với sự trợ giúp của Claude thật sự rất ấn tượng
      Tuy vậy, đoạn “vừa mở lại Cursor thì gói độc hại đã chạy” có vẻ hơi nguy hiểm
      Ngay khi có nghi ngờ, lẽ ra phải cô lập thiết bị và liên hệ đội bảo mật trước
    • Tôi cũng phát hiện ra vấn đề này gần như cùng thời điểm và theo đúng cách đó
      Nếu file .pth không hoạt động như một fork bomb thì có lẽ đã bị phát hiện muộn hơn rất nhiều
      Việc hỏi Claude đường dây liên hệ là một quyết định đúng đắn
      Vì tôi không biết đầu mối liên hệ liên quan đến PyPI, nên đã gửi mail cho maintainer và cũng đăng lên Hacker News
      Tôi nghĩ rằng dù không thuộc cộng đồng bảo mật đi nữa, ai cũng phải có thể báo cáo những lỗ hổng nghiêm trọng kiểu này
    • Tôi có kinh nghiệm quản lý chương trình công bố lỗ hổng ở nhiều công ty
      Phần lớn vấn đề đến từ những người muốn kiếm tiền nên cái gì cũng nhận là lỗ hổng
      Nhưng báo cáo của bạn có chất lượng cao, và những trường hợp như vậy sẽ được đẩy thẳng vào ưu tiên vá lỗi
      Nếu có thể xử lý ngay mà không làm gián đoạn kinh doanh thì sẽ xử lý tức thì, còn nếu nghiêm trọng thì tôi sẽ báo ngay cho CISO hoặc CTO
    • Bài viết rất hay. Tôi cảm thấy Claude đặc biệt hữu ích trong tình huống như thế này
      Nhờ báo cáo của bạn mà đã ngăn được một sự cố lớn hơn
      Bên tôi cũng đã tổng hợp nội dung liên quan thành hai bài blog
      bài viết trên blog grith.ai
    • Gần đây tôi nghe nói các dự án mã nguồn mở đang rất vất vả vì lũ báo cáo lỗ hổng và PR đổ dồn vào
      Nhưng tôi nghĩ trường hợp này là một ví dụ tốt cho thấy nhờ AI mà việc phân tích nguyên nhân và báo cáo đã nhanh hơn rất nhiều
  • Đây là lần đầu tiên tôi thấy công cụ claude-code-transcripts của mình được nhúng làm dữ liệu trong một bài blog
    Bình thường tôi chia sẻ bằng trang HTML của Gist, nên cách dùng này khá thú vị

    • Công ty chúng tôi cũng đang dùng rất tích cực
      Chúng tôi đã thử chỉnh cho hợp với phong cách blog nhưng không thành công, và điều đó lại càng khiến tôi nhận ra tầm quan trọng của trải nghiệm mặc định
      Claude cào log như thể đang quét toàn bộ máy tính của tôi, nên tôi cảm thấy cần có một hệ thống tự động biên tập log
    • Việc chia sẻ thông tin giữa các phiên Claude Code vẫn là một vấn đề lớn
      Nó đặc biệt bất tiện khi cộng tác với cả nhóm trong lúc debug khẩn cấp
  • Những yêu cầu như “có thể in nội dung script độc hại ra mà không thực thi không?” là rất nguy hiểm
    Vì các tác nhân LLM không có khái niệm về trách nhiệm, nên nếu lỡ ra lệnh thực thi thì có thể dẫn tới sự cố lớn
    Khi tải file từ PyPI thì nhất định phải làm trong môi trường sandbox

    • Tôi cũng lo đúng điểm đó
      Hễ bảo là “đừng làm” thì ngược lại tôi lại có xu hướng bám lấy nó hơn
  • Tôi nghe nói PyPI hỗ trợ “digital attestation”, nên tò mò không biết gói này có được ký hay không
    tài liệu PyPI Trusted Publishers

  • Tôi nghĩ các package registry như GitHub, npm, PyPI cần cung cấp event stream (firehose) cho phân tích bảo mật thời gian thực
    Những cuộc tấn công kiểu này đáng lẽ các máy quét tự động đã có thể bắt được ngay

    • PyPI thực ra đã cung cấp chức năng đó rồi
      Các đối tác bảo mật có thể quét package và báo cáo qua API theo hình thức mời tham gia
      Xem bài blog của PyPI
    • Sau vụ này tôi cũng đã áp dụng dependency cooldown
      bài viết liên quan
      Mục tiêu là kéo dài thời gian để các máy quét tự động phát hiện những dấu hiệu bất thường như file .pth
    • npm có feed thay đổi package, còn GitHub vận hành event firehose và bộ dữ liệu công khai trên BigQuery
    • Tôi nghĩ việc cung cấp hạ tầng như vậy nên trở thành nghĩa vụ pháp lý
      Thiệt hại kinh tế có thể quá lớn, và riêng số người bị nhiễm litellm đã vượt 47 nghìn
  • Đoạn “viết blog post, tạo PR, rồi merge tất cả trong chưa đến 3 phút” là phần gây sốc nhất
    Nhanh hơn cả thời gian đọc, nên tạo cảm giác bất an

  • Nếu không có fork bomb 11 nghìn tiến trình đó, có khi cuộc tấn công này đã ẩn mình lâu hơn nhiều

    • Tôi cũng vừa cài package là hệ thống đứng ngay nên đã tránh bị lây nhiễm
      Nếu tốc độ của quả bom bị làm chậm lại thì thiệt hại hẳn đã lớn hơn nhiều
    • Có lẽ phải gọi đây là internet worm của thế hệ này
  • Có hai cách để doanh nghiệp lớn chạy mã nguồn mở không đáng tin cậy

    1. Làm như Google, tự build mọi thứ từ source
    2. Chỉ lấy từ mirror nội bộ của công ty và xác minh chữ ký của mọi package
      Thực tế thì (1) là an toàn nhất
      Với doanh nghiệp vừa nhỏ hoặc cá nhân, ghim phiên bản phụ thuộc (pinning) và chờ đủ lâu là biện pháp phòng thủ tốt nhất
      Dùng Bazel có thể tiến gần đến cách (1), nhưng đa số vẫn không tránh khỏi phụ thuộc vào nguồn bên ngoài
  • Việc PyPI cô lập package chỉ sau 30 phút kể từ lúc nhận báo cáo là phản ứng cực nhanh

    • Dù có nhiều lo ngại rằng họ dễ bị tấn công chuỗi cung ứng, nhưng lần này tôi nghĩ đây là một ca xử lý khá tốt
  • Một trong những điểm hay nhất của AI/LLM là dân chủ hóa reverse engineering
    Trước đây đây là kỹ năng khó học mà cũng ít được đền đáp, còn bây giờ AI có thể chỉ đường

    • Nhưng vụ này không phải reverse engineering mà là vấn đề quản trị hệ thống cơ bản
      Mẫu exec(base64.b64decode(...)) là cách mà các công cụ Python thường dùng để truyền mã,
      nhưng về cơ bản thì mã chạy từ /tmp, /var/tmp hoặc /dev/shm luôn phải bị xem là cực kỳ đáng ngờ
      Nếu có các công cụ giám sát mạng như Lulu hay LittleSnitch thì có lẽ đã chặn được lưu lượng bất thường
      Tuy nhiên, tải binary lên Claude để nhờ phân tích lại là một rủi ro khác
    • Tôi cũng thấy hứng thú khi xem các video CTF, nhưng trong công việc thực tế thì hiếm khi trực tiếp gặp những chuyện như thế này