Tổng quan về Cuộc Tấn công Chuỗi Cung ứng npm
Nhiều người dùng GitHub đã báo cáo rằng gói npm phổ biến eslint-config-prettier đã được phát hành mà không có sự ủy quyền, mặc dù kho lưu trữ (repository) của nó không chứa bất kỳ thay đổi mã tương ứng nào. Vụ việc này nhanh chóng được xác nhận bởi người duy trì gói thông qua mạng xã hội, tiết lộ rằng tài khoản npm của họ đã bị xâm phạm thông qua một email lừa đảo (phishing). Cuộc tấn công này đã ảnh hưởng đến nhiều gói npm quan trọng, đánh dấu một sự kiện đáng chú ý trong chuỗi cung ứng phần mềm.
Phạm vi Gói bị Ảnh hưởng
Sự cố này không chỉ giới hạn ở một gói mà còn lan rộng ra nhiều phiên bản và gói khác, cho thấy phạm vi ảnh hưởng đáng kể. Các gói và phiên bản cụ thể bị ảnh hưởng bao gồm:
- eslint-config-prettier: các phiên bản 8.10.1, 9.1.1, 10.1.6, và 10.1.7
- eslint-plugin-prettier: các phiên bản 4.2.2 và 4.2.3
- snyckit: phiên bản 0.11.9
- @pkgr/core: phiên bản 0.2.8
- napi-postinstall: phiên bản 0.3.1
Cuộc tấn công chuỗi cung ứng này đã phân phối một mã độc mới, được đặt tên là “Scavenger”. Tên gọi này bắt nguồn từ các chuỗi ký tự lặp lại như “SCVNGR” được tìm thấy trong các biến thể của nó.
Vectơ Lây nhiễm và Cơ chế Khởi chạy
Vectơ lây nhiễm của mã độc Scavenger nhắm mục tiêu cụ thể vào các hệ thống Windows. Quá trình lây nhiễm bắt đầu bằng cách lợi dụng một kịch bản (script) có tên install.js có trong các gói npm bị xâm phạm. Kịch bản này được thiết kế để thực thi một chức năng quan trọng là logDiskSpace ngay khi gói được cài đặt.
Kịch bản install.js và Chức năng logDiskSpace
Khi được kích hoạt, chức năng logDiskSpace thực hiện một kiểm tra nền tảng để xác định xem hệ thống có phải là win32 (tức là Windows) hay không. Nếu điều kiện này được thỏa mãn, nó sẽ tạo ra một tiến trình con (child process) bằng cách sử dụng rundll32.exe. Lệnh này được dùng để tải và thực thi một thư viện liên kết động (DLL) độc hại có tên node-gyp.dll. Hash SHA256 của DLL này là c68e42f416f482d43653f36cd14384270b54b68d6496a8e34ce887687de5b441.
Thư viện node-gyp.dll này, được biên dịch cùng ngày với thời điểm các gói bị phân phối, hoạt động như một trình tải (loader) ban đầu. Ngay sau khi được tải, nó sẽ khởi tạo một luồng riêng biệt (separate thread) để bắt đầu các hoạt động cốt lõi của mã độc. Chiến dịch phishing ban đầu, sử dụng các kỹ thuật mã thiết bị (device code techniques), đã được nhà nghiên cứu bảo mật Rad mô tả chi tiết trong một bài viết riêng về các cuộc tấn công chuỗi cung ứng npm, làm rõ cách mà những kẻ tấn công đã giành được quyền truy cập ban đầu.
Mã độc Scavenger: Các Kỹ thuật Chống Phân tích Nâng cao
Trình tải của Scavenger, được viết bằng Visual Studio C++, sử dụng các biện pháp chống phân tích tinh vi để né tránh việc bị phát hiện bởi các công cụ bảo mật và nhà nghiên cứu. Những kỹ thuật này giúp mã độc tồn tại lâu hơn trên hệ thống và gây khó khăn cho quá trình đảo ngược kỹ thuật (reverse engineering).
Chống Máy ảo (Anti-VM) và Sandbox
Một trong những kỹ thuật phòng thủ chính là thực hiện các kiểm tra chống máy ảo (anti-VM). Mã độc truy vấn bảng firmware SMBIOS thô thông qua hàm GetSystemFirmwareTable. Bằng cách này, nó có thể quét các chữ ký đặc trưng của môi trường ảo hóa như “VMware”, “qemu”, hoặc “QEMU”. Nếu bất kỳ chữ ký nào được tìm thấy, mã độc có thể ngừng hoạt động hoặc thay đổi hành vi để tránh bị phân tích trong môi trường ảo hóa.
Kiểm tra Trình gỡ lỗi (Anti-Debugger)
Ngoài ra, Scavenger còn thực hiện các kiểm tra để phát hiện sự hiện diện của các công cụ phân tích hoặc trình gỡ lỗi (debugger). Mã độc liệt kê các mô-đun tiến trình để tìm kiếm các DLL liên quan đến phần mềm diệt virus hoặc các công cụ gỡ lỗi, ví dụ như snxhk.dll (Avast), SbieDll.dll (Sandboxie), và cmdvrt32.dll (Comodo), cũng như các công cụ như vehdebug-x86_64.dll (CheatEngine). Sự hiện diện của các DLL này cho thấy môi trường đang được giám sát hoặc phân tích. Mã độc cũng xác minh các thuộc tính hệ thống, đảm bảo rằng hệ thống có nhiều hơn ba bộ xử lý (processors) thông qua NtQuerySystemInformation và xác nhận rằng nó không chạy trong môi trường console với WriteConsoleW. Nếu bất kỳ kiểm tra nào thất bại, mã độc sẽ cố ý gây ra lỗi con trỏ null (null-pointer crash) để chấm dứt hoạt động, một kỹ thuật phổ biến để né tránh phân tích.
Giải quyết Hàm động (Dynamic Function Resolution)
Để tăng cường khả năng che giấu, mã độc giải quyết các hàm động (dynamically resolve functions) thay vì nhập tĩnh chúng. Điều này được thực hiện bằng cách sử dụng một thuật toán băm CRC32 trên các mô-đun đã tải từ Process Environment Block (PEB). Mã độc chuyển đổi tên DLL từ Unicode sang ASCII và tính toán giá trị băm mà không lưu trữ chúng vào bộ nhớ đệm (caching), gây khó khăn hơn cho việc phân tích tĩnh và động. Kỹ thuật này khiến việc xác định các hàm API mà mã độc sử dụng trở nên phức tạp hơn, vì chúng không được liệt kê rõ ràng trong bảng nhập (import table) của PE.
Gỡ bỏ Hook API (API Unhooking)
Một kỹ thuật tiên tiến khác là khả năng gỡ bỏ các hook API được thiết lập bởi các giải pháp bảo mật như Endpoint Detection and Response (EDR). Mã độc sử dụng các cuộc gọi hệ thống gián tiếp (indirect syscalls) để bỏ qua các hook trên các hàm API quan trọng như NtSetInformationThread và NtQuerySystemInformation. Bằng cách vá (patching) các lệnh tại thời gian chạy (runtime), mã độc có thể thực thi các hàm này trực tiếp mà không bị các hệ thống EDR giám sát hoặc chặn, cho phép nó thực hiện các hoạt động độc hại một cách ẩn danh hơn.
Mã hóa Chuỗi (String Encryption)
Tất cả các chuỗi nhạy cảm trong mã độc, bao gồm các thông báo lỗi, URL C2, hoặc các khóa giải mã, đều được mã hóa. Chúng được mã hóa bằng các khóa XOR cụ thể như 0x39541b2f8f3ef92d và chỉ được giải mã khi cần thiết (on-the-fly decryption). Điều này làm cho việc phân tích tĩnh các chuỗi trở nên vô ích và yêu cầu các nhà phân tích phải chạy mã độc trong môi trường được kiểm soát để quan sát các chuỗi đã giải mã.
Giao tiếp Command-and-Control (C2) và Chức năng Stealer Giai đoạn Hai
Scavenger thiết lập các kênh liên lạc với máy chủ Command-and-Control (C2) để nhận lệnh và gửi dữ liệu đã đánh cắp. Giao tiếp này được bảo vệ bằng các biện pháp mã hóa để tránh bị phát hiện và phân tích.
Kênh Liên lạc C2
Mã độc sử dụng thư viện libcurl để thiết lập kết nối với máy chủ C2. Dữ liệu được gửi đi được mã hóa bằng thuật toán XXTEA, có thể nhận dạng qua hằng số DELTA 0x9e3779b9. Các payload được mã hóa sau đó được mã hóa lại bằng Base64 và gửi đến các endpoint cụ thể trên máy chủ C2. Ví dụ, endpoint /c/k2 được sử dụng để gửi định danh chiến dịch (campaign IDs), trong khi /c/v được dùng cho các kiểm tra tính toàn vẹn (integrity checks). Kiến trúc này cho phép kẻ tấn công điều khiển mã độc và thu thập thông tin một cách hiệu quả.
Stealer Dữ liệu Chromium Giai đoạn Hai
Mã độc Scavenger cũng triển khai một stealer giai đoạn hai (second-stage stealer) với các kỹ thuật tương tự như loader để tránh bị phát hiện. Stealer này tập trung vào việc đánh cắp dữ liệu từ các trình duyệt dựa trên Chromium. Các mục tiêu cụ thể bao gồm các tạo phẩm (artifacts) của Chromium như Extensions, ServiceWorkerCache, DawnWebGPUCache, và Visited Links. Mục tiêu chính của giai đoạn này là thu thập dữ liệu nhạy cảm để đánh cắp, bao gồm các mã thông báo xác thực (authentication tokens), dữ liệu phiên (session data), hoặc lịch sử duyệt web, có khả năng dẫn đến việc chiếm đoạt tài khoản người dùng hoặc truy cập sâu hơn vào mạng.
Các Chỉ số Thỏa hiệp (IOCs) và Dấu hiệu Nhận biết
Việc nhận diện các chỉ số thỏa hiệp (IOCs) là rất quan trọng để phát hiện và ngăn chặn mã độc Scavenger. Các chi tiết bị rò rỉ và các dấu hiệu hoạt động giúp xác nhận danh tính và cách thức hoạt động của mã độc.
IOCs Chính
Dưới đây là các chỉ số thỏa hiệp quan trọng liên quan đến mã độc Scavenger:
- SHA256 của node-gyp.dll (Loader):
c68e42f416f482d43653f36cd14384270b54b68d6496a8e34ce887687de5b441
- PDB Path bị lộ (đường dẫn debug):
C:\Users\user\Desktop\X\scavenger\scavenger-main\scavenger-client\x64\Release\dropper-cmd.pdb
- Endpoints C2:
/c/k2/c/v
Đường dẫn PDB bị lộ đặc biệt quan trọng vì nó không chỉ xác nhận tên “Scavenger” mà còn cho thấy sự cẩu thả của kẻ tấn công. Ngoài ra, việc sử dụng các cuộc gọi WinExec kém tinh vi để thực thi các lệnh curl nhằm tìm nạp các payload bổ sung cũng là một dấu hiệu nhận biết.
Kết nối với Các Chiến dịch Trước đây
Các biến thể của mã độc Scavenger có liên quan đến các chiến dịch trước đây, bao gồm một vụ lây nhiễm thực thi BeamNG. Điều này cho thấy kẻ tấn công có thể đã sử dụng lại các công cụ hoặc kỹ thuật từ các hoạt động trước đó, hoặc Scavenger là một phần của một chiến dịch rộng lớn hơn với nhiều giai đoạn và mục tiêu khác nhau. Việc theo dõi các kết nối này giúp các nhà nghiên cứu hiểu rõ hơn về hoạt động của nhóm tấn công và phát triển các biện pháp phòng thủ toàn diện hơn.










