Bốn gói npm bị xâm nhập trong namespace @asyncapi đã được phát hiện đang phân phối một botnet loader đa giai đoạn, theo các phát hiện từ OX Security, SafeDep, Socket và StepSecurity.
Các gói bị ảnh hưởng được liệt kê dưới đây:
- @asyncapi/[email protected]
- @asyncapi/[email protected]
- @asyncapi/[email protected]
- @asyncapi/specs (v6.11.2, v6.11.2-alpha.1)
"Các gói bị xâm nhập triển khai một payload giai đoạn một đã được làm mờ (obfuscated) nhằm tải xuống một payload giai đoạn hai được mã hóa, được xác định là Miasma, từ IPFS," Socket cho biết.
Các gói độc hại chứa một implant JavaScript ẩn, mỗi gói bao gồm một tệp mã nguồn được tiêm vào để giải mã thành cùng một trình tải xuống (downloader) giai đoạn hai. Không giống như các phiên bản trước đó sử dụng install hooks để kích hoạt thực thi payload JavaScript, mã độc trong trường hợp này được chạy khi module bị nhiễm được tải bởi Node.js, sau đó nó khởi chạy một node chạy ngầm tách biệt để tải xuống và thực thi mã độc từ IPFS.
Cấu trúc của mã độc Miasma
Payload giai đoạn tiếp theo là một trình tải JavaScript được mã hóa có tên "sync.js", được ghi vào các đường dẫn cụ thể của hệ điều hành và thực thi. URL của trình tải xuống là "ipfs[.]io/ipfs/QmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9". Trình tải này chứa hai thành phần:
- Payload JavaScript cuối cùng được mã hóa, giải mã thành framework tác vụ Miasma.
- Một blob mã hóa lớn được sử dụng bởi framework spawn-chain của runtime.
Framework này đóng gói 744 module và được xây dựng như một framework dòng lệnh hỗ trợ sáu kênh liên lạc command-and-control (C2) độc lập sử dụng HTTP, Nostr relay, IPFS, BitTorrent DHT, libp2p GossipSub P2P mesh và một hợp đồng thông minh Ethereum.
Ngoài việc tạo điều kiện cho hành vi trộm cắp credential, AI tool poisoning, di chuyển ngang (lateral movement) trong mạng LAN và phát tán kiểu worm trên các kho lưu trữ npm, PyPI và Cargo, Miasma còn có cơ chế persistence (duy trì sự hiện diện) riêng, thiết lập các khóa tự khởi động trong systemd, crontab, macOS launchd và Windows Registry.
"Mặc dù mã độc này có một số điểm tương đồng với các chiến dịch Shai-Hulud và Miasma, đồng thời chứa chuỗi 'Miasma' nhiều lần trong mã nguồn, nhưng nó không hoàn toàn giống với chúng, cũng như không được quy kết cho các chiến dịch Miasma/Shai-Hulud/TeamPCP mà chúng ta đã thấy trước đây," Moshe Siman Tov Bustan từ OX Security nhận định.
Hơn nữa, nó còn tích hợp một "dead man's switch" để theo dõi một token bị đánh cắp và kích hoạt xóa danh mục nếu token đó bị thu hồi. Nó cũng tránh các hệ thống được xác định là sandbox hoặc môi trường ảo, cũng như các máy tính có ngôn ngữ hiện tại là tiếng Nga hoặc đã cài đặt các công cụ bảo mật từ CrowdStrike, SentinelOne, Microsoft Defender, CarbonBlack, Cylance, Osquery, Tanium và Qualys installed.
Tấn công thông qua Chuỗi cung ứng và CI/CD
Theo StepSecurity, kẻ tấn công được cho là đã giành được quyền push vào các kho lưu trữ (repository) và sử dụng chính pipeline phát hành GitHub Actions hợp lệ của dự án để xuất bản các gói với chứng thực nguồn gốc OIDC hợp lệ. Cuộc tấn công chuỗi cung ứng này không liên quan đến việc đánh cắp token npm.
"Cả hai cuộc tấn công đều là sự xâm nhập vào CI/CD pipeline, không phải do token npm bị đánh cắp hay do những người duy trì (maintainer) có ý đồ xấu," nhà nghiên cứu bảo mật Rohan Prabhu cho biết. "Kẻ tấn công đã push các commit dưới một danh tính git giả và để quy trình phát hành thực thực tế của mỗi kho lưu trữ thực hiện việc xuất bản thông qua tích hợp trusted-publisher của npm với GitHub OIDC."
Các gói kết quả mang theo các chứng thực nguồn gốc SLSA hợp lệ, chỉ chứng minh rằng quy trình làm việc được ủy quyền của dự án đã tạo ra chúng, chứ không chứng minh các commit kích hoạt là hợp lệ. Chứng thực nguồn gốc không bảo vệ chống lại việc thông tin đăng nhập push bị xâm phạm.
Tất cả năm phiên bản độc hại kể từ đó đã bị gỡ bỏ khỏi kho lưu trữ npm. Khuyến cáo nên xử lý bất kỳ endpoint nào đã import hoặc thực thi một trong các phiên bản gói bị ảnh hưởng như thể đã bị xâm nhập. Tuy nhiên, cần lưu ý rằng mức độ phơi nhiễm phụ thuộc vào việc module bị nhiễm có được tải như một phần của quá trình build hoặc quy trình làm việc của nhà phát triển hay không.
"Không có script preinstall/postinstall/install nào trong ba tệp package.json," StepSecurity cho biết. "Dropper này được kích hoạt khi module bị nhiễm được gọi bằng require() trong quá trình sử dụng bình thường: thời điểm một tiến trình build hoặc CI thực sự gọi vào thư viện, chứ không phải lúc thực hiện lệnh npm install."