Các tác nhân đe dọa đằng sau cuộc supply chain attack nhắm vào công cụ quét Trivy phổ biến bị nghi ngờ đang thực hiện các cuộc tấn công tiếp theo, dẫn đến việc một số lượng lớn các gói npm bị xâm phạm bởi một loại worm tự lây lan chưa từng được ghi nhận trước đây có tên CanisterWorm.
Tên gọi này là một tham chiếu đến việc mã độc sử dụng một ICP canister, vốn là các smart contract chống giả mạo trên blockchain Internet Computer, hoạt động như một dead drop resolver. Sự phát triển này đánh dấu lần đầu tiên việc lạm dụng một ICP canister được ghi nhận công khai với mục đích cụ thể là lấy thông tin máy chủ command-and-control (C2), nhà nghiên cứu bảo mật Aikido Security Charlie Eriksen cho biết.
Các gói npm bị ảnh hưởng
Dưới đây là danh sách các gói bị ảnh hưởng:
- 28 gói trong @EmilGroup scope
- 16 gói trong @opengov scope
- @teale.io/eslint-config
- @airtm/uuid-base32
- @pypestream/floating-ui-dom
Diễn biến này xảy ra chỉ một ngày sau khi các tác nhân đe dọa tận dụng một credential bị xâm phạm để phát hành các bản Trivy, trivy-action và setup-trivy độc hại chứa một credential stealer. Một cybercriminal operation tập trung vào đám mây được biết đến với tên TeamPCP bị nghi ngờ đứng sau các cuộc tấn công này.
Cơ chế lây nhiễm và duy trì
Chuỗi lây nhiễm liên quan đến các gói npm bao gồm việc tận dụng một postinstall hook để thực thi một loader, sau đó thả một Python backdoor chịu trách nhiệm liên hệ với ICP canister dead drop để lấy một URL trỏ đến payload giai đoạn tiếp theo. Thực tế là hạ tầng dead drop được phi tập trung hóa khiến nó kiên cường và khó bị gỡ bỏ.
"Bộ điều khiển canister có thể thay đổi URL bất cứ lúc nào, đẩy các binaries mới đến tất cả các máy chủ bị nhiễm mà không cần chạm vào implant," Eriksen nói.
Khả năng duy trì (Persistence) được thiết lập thông qua một systemd user service, được cấu hình để tự động khởi động Python backdoor sau 5 giây nếu nó bị chấm dứt vì lý do nào đó, bằng cách sử dụng chỉ thị "Restart=always". Dịch vụ systemd này giả mạo là công cụ PostgreSQL ("pgmon") nhằm mục đích tránh bị phát hiện.
Cơ chế hoạt động của Backdoor
Backdoor, như đã đề cập trước đó, gọi đến ICP canister với User-Agent trình duyệt giả mạo cứ sau 50 phút để lấy URL dưới dạng plaintext. URL sau đó được phân tích cú pháp để tìm nạp và chạy executable.
"Nếu URL chứa youtube[.]com, script sẽ bỏ qua nó," Eriksen giải thích. "Đây là trạng thái ngủ đông của canister. Kẻ tấn công kích hoạt implant bằng cách trỏ canister đến một binary thực tế, và vô hiệu hóa nó bằng cách chuyển trở lại một liên kết YouTube. Nếu kẻ tấn công cập nhật canister để trỏ đến một URL mới, mọi máy bị nhiễm sẽ nhận được binary mới trong lần thăm dò tiếp theo. Binary cũ vẫn tiếp tục chạy ẩn vì script không bao giờ giết các process trước đó."
Điều đáng chú ý là một kill switch dựa trên youtube[.]com tương tự cũng đã được Wiz gắn cờ liên quan đến Trivy binary bị trojan hóa (phiên bản 0.69.4), vốn cũng liên hệ với cùng ICP canister thông qua một Python dropper ("sysmon.py"). Tính đến thời điểm hiện tại, URL được trả về bởi C2 là một video YouTube rickroll.
The Hacker News phát hiện ra rằng ICP canister hỗ trợ ba phương thức – get_latest_link, http_request, update_link – cho phép tác nhân đe dọa sửa đổi hành vi bất cứ lúc nào để phục vụ một payload thực tế.
Sự tự lây lan của CanisterWorm
Đồng thời, các gói đi kèm với một tệp "deploy.js" mà kẻ tấn công chạy thủ công để phát tán payload độc hại đến mọi gói mà một npm token bị đánh cắp cung cấp quyền truy cập theo cách lập trình. Worm, được đánh giá là được "vibe-coded" bằng một công cụ artificial intelligence (AI), không hề cố gắng che giấu chức năng của nó.
"Điều này không được kích hoạt bởi npm install," Aikido cho biết. "Đây là một công cụ độc lập mà kẻ tấn công chạy với các token bị đánh cắp để tối đa hóa phạm vi ảnh hưởng (blast radius)."
Tệ hơn nữa, một phiên bản tiếp theo của CanisterWorm được phát hiện trong "@teale.io/eslint-config" phiên bản 1.8.11 và 1.8.12 đã được phát hiện tự lây lan mà không cần sự can thiệp thủ công.
Không giống như "deploy.js", vốn là một script độc lập mà kẻ tấn công phải thực thi bằng các npm tokens bị đánh cắp để đẩy một phiên bản độc hại của các gói npm lên registry, biến thể mới này tích hợp chức năng này vào "index.js" trong một hàm findNpmTokens() được chạy trong giai đoạn postinstall để thu thập npm authentication tokens từ máy của nạn nhân.
Sự khác biệt chính ở đây là script postinstall, sau khi cài đặt backdoor cố định, cố gắng định vị mọi npm token từ môi trường của nhà phát triển và khởi động worm ngay lập tức với các token đó bằng cách khởi chạy "deploy.js" dưới dạng một process nền hoàn toàn tách rời.
Thú vị thay, tác nhân đe dọa được cho là đã hoán đổi ICP backdoor payload thành một dummy test string ("hello123"), có thể là để đảm bảo rằng toàn bộ chuỗi tấn công đang hoạt động như dự kiến trước khi thêm mã độc.
"Đây là điểm mà cuộc tấn công chuyển từ 'tài khoản bị xâm phạm phát tán mã độc' sang 'mã độc xâm phạm nhiều tài khoản hơn và tự phát tán'," Eriksen nói. "Mọi nhà phát triển hoặc CI pipeline cài đặt gói này và có một npm token có thể truy cập đều trở thành một phương tiện lây lan không chủ ý. Các gói của họ bị nhiễm, người dùng cuối của họ cài đặt những gói đó, và nếu bất kỳ ai trong số họ có token, chu kỳ sẽ lặp lại."
(Đây là một câu chuyện đang diễn ra. Vui lòng kiểm tra lại để biết thêm chi tiết.)