2 điểm bởi GN⁺ 29 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • GitHub Action chính thức đã bị can thiệp bằng cách cập nhật cưỡng bức thẻ và dẫn đến cuộc tấn công chuỗi cung ứng phát tán mã độc
  • Kẻ tấn công đã thay 75 trong số 76 thẻ bằng commit độc hại, ảnh hưởng đến khoảng hơn 10.000 workflow
  • Script bị can thiệp hoạt động theo 3 giai đoạn: thu thập, mã hóa và đánh cắp dữ liệu bí mật, có chứa mã TeamPCP Cloud stealer
  • Các thẻ bị nhiễm vẫn còn hoạt động; xác nhận rằng chỉ @0.35.0 hoặc một commit SHA cụ thể là an toàn
  • Bắt buộc phải thay toàn bộ thông tin xác thực và dùng commit SHA được ghim cố định; image trên Docker Hub cũng được xác nhận bị nhiễm tương tự

Tổng quan về cuộc tấn công chuỗi cung ứng nhắm vào Trivy GitHub Actions

  • GitHub Action chính thức của Trivy (aquasecurity/trivy-action) đã bị kẻ tấn công can thiệp bằng phương thức cập nhật cưỡng bức thẻ (force-push) để phát tán mã độc
  • Kẻ tấn công đã thay 75 trong số 76 thẻ phiên bản bằng commit độc hại để chúng được tự động thực thi trong pipeline CI/CD
  • Có khoảng hơn 10.000 file workflow GitHub đang tham chiếu đến action này, nên phạm vi ảnh hưởng rất rộng
  • Các thẻ bị nhiễm vẫn còn hoạt động, và xác nhận rằng chỉ @0.35.0 là phiên bản an toàn duy nhất
  • Socket đã phát hiện theo thời gian thực 182 sự kiện GitHub Action độc hại kể từ 19:15 UTC, được phân loại thành các nhóm Backdoor, InfostealerReconnaissance

Nguyên nhân và cách thức cuộc tấn công diễn ra

  • Theo maintainer của Trivy, vụ tấn công lần này xảy ra do bị đánh cắp thông tin xác thực có quyền ghi
    • Trong sự cố xâm nhập trước đó vào đầu tháng 3, bí mật trong môi trường CI đã bị lộ; quá trình xoay vòng (rotating) không hoàn tất nên một phần thông tin xác thực mới vẫn nằm trong tay kẻ tấn công
    • Kẻ tấn công dùng những thông tin xác thực này để thực hiện cập nhật thẻ đã xác thực mà không cần khai thác lỗ hổng nào của GitHub
  • Thay vì push lên nhánh hoặc tạo bản phát hành mới, kẻ tấn công đã cưỡng bức ghi đè các thẻ hiện có bằng commit mới
    • Mỗi thẻ đều sao chép metadata của commit gốc (tác giả, email, dấu thời gian, thông điệp commit) để ngụy trang như bình thường
    • Tuy nhiên, commit gốc có chữ ký GPG còn commit của kẻ tấn công thì thiếu chữ ký, và ngày của commit cha lại không khớp vì là năm 2026
  • Ngay cả khi GitHub có hiển thị trạng thái Immutable Release, vẫn có khả năng kẻ tấn công đã phát hành ở trạng thái độc hại rồi mới khóa lại
    • Vì vậy, không nên dựa vào huy hiệu “Immutable”; cách sử dụng an toàn duy nhất là ghim cố định commit SHA (pinning)

Cấu trúc thao túng thẻ

  • Kẻ tấn công tạo commit mới dựa trên commit mới nhất của nhánh master (57a97c7e)
    • Chỉ thay file entrypoint.sh bằng phiên bản độc hại, còn các file khác được giữ nguyên
    • Mỗi thẻ đều sao chép nguyên số PR, thông điệp commit và thông tin tác giả ban đầu để giả mạo
  • Trên trang GitHub Releases, nếu xuất hiện dòng “0 commits to master since this release” thì có thể xem đó là dấu hiệu trực quan của thẻ đã bị can thiệp
  • Lý do duy nhất khiến thẻ 0.35.0 không bị sửa đổi là vì nó đã trỏ sẵn tới HEAD của master

Cấu trúc payload độc hại

  • entrypoint.sh bị can thiệp có tổng cộng 204 dòng; dòng 4~105 chứa mã Infostealer, sau đó mới là mã quét Trivy bình thường
  • Mã độc gồm 3 giai đoạn
    • Giai đoạn 1: Thu thập (Collection) — trích xuất bí mật từ bộ nhớ tiến trình runner và hệ thống file
    • Giai đoạn 2: Mã hóa (Encryption) — mã hóa dữ liệu thu thập được bằng AES-256-CBC và RSA-4096
    • Giai đoạn 3: Đánh cắp dữ liệu (Exfiltration) — gửi dữ liệu đến tên miền do kẻ tấn công kiểm soát hoặc đến tài khoản GitHub của nạn nhân
  • Giai đoạn 1: Thu thập bí mật

    • Đọc biến môi trường của các tiến trình runner GitHub Actions (Runner.Worker, Runner.Listener, runsvc, run.sh) từ /proc/<pid>/environ và trích xuất các mục có chứa từ khóa env, ssh
    • Trên runner do GitHub lưu trữ, script dump bộ nhớ bằng Python được chạy bằng sudo để tìm mẫu "isSecret":true trong bộ nhớ tiến trình Runner.Worker
    • Trên runner tự lưu trữ, mã này chạy trình thu thập thông tin xác thực từ hệ thống file được xác định là TeamPCP Cloud stealer
      • Bao gồm nhiều mục tiêu như khóa SSH, thông tin xác thực AWS/GCP/Azure, token Kubernetes, cấu hình Docker, mật khẩu DB, file môi trường, khóa TLS, cấu hình VPN, URL webhook, khóa ví và nhiều dữ liệu khác
  • Giai đoạn 2: Mã hóa

    • Tạo session key 32 byte bằng openssl rand, sau đó mã hóa dữ liệu bằng AES-256-CBC
    • Session key được mã hóa bằng khóa công khai RSA-4096 với padding OAEP
    • Dữ liệu đã mã hóa (payload.enc) và session key (session.key.enc) được đóng gói thành tpcp.tar.gz
  • Giai đoạn 3: Đánh cắp dữ liệu

    • Kênh thứ nhất: gửi HTTPS POST tới https://scan[.]aquasecurtiy[.]org (dùng tên miền gõ sai của aquasecurity)
    • Kênh thứ hai: nếu thất bại, dùng GitHub Personal Access Token của nạn nhân để tạo một kho lưu trữ công khai tên tpcp-docs
      • Tải tpcp.tar.gz lên dưới dạng release asset → kẻ tấn công dùng tìm kiếm GitHub để phát hiện kho này và thu thập dữ liệu
    • Cố gắng vượt tường lửa bằng cách lợi dụng hạ tầng GitHub, nên khả năng né tránh phát hiện cao
    • Cuối cùng, mã độc xóa các file tạm để giảm dấu vết

Kẻ tấn công và bên đứng sau

  • Trong chú thích của mã độc có ghi rõ “TeamPCP Cloud stealer”
    • TeamPCP (DeadCatx3, PCPcat, ShellForce) là nhóm tấn công nhắm vào môi trường cloud-native, từng có các trường hợp khai thác lỗ hổng Docker API, Kubernetes, Redis và dashboard Ray
    • Vào tháng 2 năm 2026, Flare và The Hacker News từng đưa tin về chiến dịch ransomware, đánh cắp dữ liệu và đào tiền mã hóa của nhóm này
  • Khả năng thu thập khóa validator Solana và ví tiền mã hóa cũng phù hợp với động cơ tài chính

Ứng phó và khuyến nghị

  • Ngừng sử dụng mọi thẻ phiên bản của Trivy Action, chỉ dùng commit SHA 57a97c7e7821a5776cebc9bb87c984fa69cba8f1 hoặc thẻ 0.35.0
  • Các pipeline bị nhiễm cần được coi là đã rò rỉ hoàn toàn bí mật, và phải thay ngay mọi thông tin xác thực cloud, khóa SSH, token API, mật khẩu DB, token Docker
  • Khuyến nghị kiểm tra xem trong tổ chức GitHub có tồn tại kho tpcp-docs hay không, đồng thời rà soát log của trivy-action được chạy sau 19:00 UTC ngày 19/3

Chỉ dấu xâm nhập (IOCs)

  • Chỉ dấu mạng: scan[.]aquasecurtiy[.]org
  • Hash file: 18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a (entrypoint.sh)
  • GitHub Actions bị nhiễm: mọi phiên bản từ aquasecurity/trivy-action@0.0.1 đến @0.34.2 (tổng cộng 75 thẻ)

Cập nhật thêm (22/3)

  • Trên Docker Hub cũng xác nhận rằng các image Trivy (0.69.4, 0.69.5, 0.69.6, latest) đã bị nhiễm cùng payload Infostealer
  • Thẻ latest đã bị trỏ tới image độc hại và được phân phối tới người dùng trong thời gian bị lộ nhiễm
  • Có thể xem chi tiết liên quan trong báo cáo riêng của Socket “Trivy Docker Images Compromised”

1 bình luận

 
Ý kiến trên Hacker News
  • Thắc mắc vì sao GitHub không bắt buộc quản lý phiên bản bất biến (immutable versioning) cho Actions
    Hướng dẫn bảo mật khuyên nên pin bằng commit SHA, nhưng có vẻ nếu ngay từ đầu không cho phép phát hành Action nếu chưa được pin thì có thể giảm bớt những vấn đề như thế này

    • Những thảo luận kiểu này lúc nào cũng có hai mặt
      Từ góc nhìn của đội bảo mật, phiên bản được pin sẽ an toàn hơn, nhưng đồng thời nếu các bản cập nhật bảo mật không được tự động áp dụng thì cũng lại thành rủi ro
      Cuối cùng vẫn cần một giải pháp đáp ứng được cả hai mà không làm tổn hại năng suất
      Muốn gọi đây là “nghịch lý của pinning
    • Có vẻ GitHub Actions đang đi theo mô hình git tag, nên nghĩ rằng hiện tại rất khó thay đổi cấu trúc này
      Dù vậy, sớm muộn gì cũng phải bắt đầu công việc thay đổi đó
    • Nếu phiên bản đã pin sẵn vốn đã ở trạng thái bị nhiễm độc thì sao?
      Cho phép cập nhật đôi khi lại có thể tăng cường bảo mật
      Đây là vấn đề khá giống tranh luận giữa liên kết tĩnh và liên kết động
      Hơn nữa, Trivy Action vốn dĩ đã được thiết kế để luôn lấy phiên bản mới nhất
  • Sự cố lần này là lời cảnh báo rằng các sản phẩm bảo mật chuỗi cung ứng (supply chain security) trên thực tế có thể mong manh không kém chính stack mà chúng muốn bảo vệ
    Đặc biệt, những công cụ bảo mật kiểu “chạy chúng tôi ở khắp mọi nơi” lại tạo ra một vector tấn công mới, nơi chỉ một lần bị xâm nhập cũng có thể đồng thời đẩy vô số người dùng vào rủi ro

  • Ban đầu cứ tưởng Trivy đã không thực hiện xoay vòng thông tin xác thực (rotation) đúng cách
    Nhưng họ giải thích rằng “trong quá trình xoay vòng không mang tính nguyên tử (non-atomic), kẻ tấn công có thể đã biết được token mới”
    GitHub không hiển thị lại token sau khi cấp phát, nhưng điều này có thể khác tùy theo phương thức xác thực đã dùng

    • Tác giả OpenClaw cũng nói rằng mình từng gặp trải nghiệm tương tự
      Ngay sau khi tạo tổ chức GitHub mới, tên đã bị chiếm mất, nên họ phải yêu cầu GitHub xử lý tạo theo cách nguyên tử
  • Đây đúng là vụ việc mà câu “phải quét lỗ hổng, chứ đừng trở thành lỗ hổng” ứng nghiệm một cách hoàn hảo

    • Thậm chí còn có câu đùa kiểu “khi bạn nhìn vào lỗ hổng, lỗ hổng cũng nhìn lại bạn
  • Có vụ liên quan là Trivy bị xâm phạm chuỗi cung ứng tạm thời

    • Cách gọi “tạm thời” nghe có vẻ là một cách nói quá nhẹ nhàng
  • Vào ngày 22 tháng 3, kẻ tấn công đã dùng thông tin xác thực bị đánh cắp để phát hành các image DockerHub Trivy v0.69.5 và v0.69.6 độc hại
    (liên kết thông báo bảo mật)
    Có hai sự cố vào ngày 19 và 22 tháng 3, và có vẻ kẻ tấn công đã liên tục duy trì quyền truy cập bất chấp hai lần xoay vòng thông tin xác thực

    • Thực tế thì từ tháng 2 đã có xâm phạm toàn bộ repository, và đây là lần tấn công thành công thứ ba của cùng một kẻ tấn công
  • Hai tuần qua là khoảng thời gian tệ nhất
    Vì Trivy bị xâm nhập nên giờ phải xử lý vô số báo cáo bảo mật và các cuộc họp

  • Đây là bài học rằng “làm phần mềm bảo mật không có nghĩa là chắc chắn giỏi”
    Đội bảo mật của chúng tôi cũng hằng tháng đều muốn đưa thêm scanner mới vào, nhưng nếu cho phép quyền truy cập quá rộng như họ yêu cầu thì có lẽ đã bị xâm nhập nhiều lần rồi

    • Trước đây tôi từng kiểm toán (audit) GitHub Actions của Trivy, và setup-trivy Action có cấu trúc clone nguyên nhánh chính rồi chạy shell script
      Tức là cho phép thực thi mã tùy ý trong mọi workflow CI
      Aqua đã bị xâm nhập từ đầu tháng này, sau hai lần cô lập thất bại thì đến cả tài khoản Docker Hub cũng bị thủng
      Giờ tôi nghĩ họ cần đến sự hỗ trợ của chuyên gia bên ngoài
    • Cấp quyền truy cập quá rộng cho “công cụ bảo mật” không phải là giảm rủi ro mà là khuếch đại rủi ro
      Phần lớn chỉ là các máy tạo báo cáo ồn ào, và nếu kẻ tấn công đã vào được bên trong thì chúng chẳng phòng thủ được gì
      Scanner mới nên chỉ được truy cập dữ liệu ở chế độ chỉ đọc trong sandbox cô lập, và không nên cấp quyền production cho đến khi được xác minh đầy đủ
      Nếu không thì chẳng khác gì đăng khóa bí mật lên pastebin
    • Bảo mật doanh nghiệp dạo này là kiểu cài giải pháp bảo mật endpoint lên mọi thiết bị rồi gửi toàn bộ log vào dashboard AI
      Nó đã trở thành một nền văn hóa bảo mật kiểu “di chuyển thật nhanh và phá hỏng mọi thứ”
    • Bộ phận bảo mật trên thực tế gần như không có lựa chọn “trên thị trường không có sản phẩm nào dùng được nên sẽ không dùng gì cả”
      Vì thế mới hình thành văn hóa triển khai phần mềm bảo mật chất lượng thấp bằng mọi giá
      Cá nhân tôi không nghĩ Trivy là công cụ tệ, và công ty chúng tôi cũng đang dùng
      Chỉ là bên tôi pin phiên bản bằng Nix và tự viết workflow Actions nên không bị ảnh hưởng bởi vụ xâm nhập lần này
  • Kẻ tấn công đã có thể thực hiện force-update tag trong trạng thái đã xác thực
    Chuyện này lẽ ra đã có thể ngăn được chỉ bằng cách bật thiết lập cũ của GitHub là “cấm ghi đè tag
    Càng lặp lại những vụ như thế này càng thấy cần các tiêu chuẩn kiểu Software Building Code
    Tò mò không biết đến năm 2026 sẽ còn có thêm bao nhiêu lý do như vậy nữa