Khám phá sự lây nhiễm của worm Shai-Hulud trong các cuộc tấn công chuỗi cung ứng

10:33 | 30/09/2025

Ngày nay, không có gì ngạc nhiên khi các mô-đun độc hại đang trở nên phổ biến hơn. Khi một tài khoản bảo trì cho các mô-đun hoặc một gói phụ thuộc phổ biến bị xâm phạm, nó có thể nhanh chóng phát triển thành một cuộc tấn công chuỗi cung ứng. Những vụ xâm phạm như vậy hiện là một vectơ tấn công thường xuyên có xu hướng giữa các tác nhân đe dọa. Chỉ riêng trong tháng 8/2025, đã có hai sự cố lớn liên quan đến các mô-đun độc hại. Bài viết này sẽ cùng tìm hiểu và khám phá một vụ xâm phạm gần đây liên quan đến việc lây nhiễm npm do phần mềm độc hại Shai-Hulud gây ra, dựa trên báo cáo của hãng bảo mật Kasperksy.

Tổng quan

Worm Shai-Hulud có khả năng đánh cắp dữ liệu nhạy cảm, làm rò rỉ các kho lưu trữ riêng tư của các tổ chức, chiếm đoạt thông tin đăng nhập từ nạn nhân để lây nhiễm sang các gói khác và phát tán chúng. Hơn 500 gói npm đã bị nhiễm trong sự cố mới nhất, bao gồm một gói có hơn hai triệu lượt tải xuống mỗi tuần.

Do đó, nếu các nhà phát triển tích hợp các gói độc hại này vào dự án có nguy cơ mất dữ liệu nhạy cảm và thư viện của họ cũng có thể bị lây nhiễm Shai-Hulud. Phần mềm độc hại này chiếm quyền kiểm soát tài khoản và đánh cắp secret để tạo ra các mô-đun bị nhiễm mới, từ đó lây lan mối đe dọa dọc theo chuỗi phụ thuộc.

Mã độc của Shai-Hulud sẽ thực thi khi một gói bị nhiễm được cài đặt. Sau đó, nó phát hành các bản phát hành độc hại cho tất cả các gói mà nạn nhân có quyền cập nhật. Khi gói bị nhiễm được cài đặt từ npm registry trên hệ thống của nạn nhân, một lệnh đặc biệt sẽ tự động được thực thi. Lệnh này khởi chạy một tập lệnh độc hại có kích thước hơn 3 MB, tên là bundle[.]js, chứa một số mô-đun mã nguồn mở hợp pháp.

Các mô-đun chính bundle[.]jsbao gồm:

- Thư viện để tương tác với các dịch vụ đám mây AWS.

- Mô-đun GCP truy xuất metadata từ môi trường Google Cloud Platform.

- Các chức năng của TruffleHog, một công cụ rà quét nguồn dữ liệu để tìm kiếm thông tin nhạy cảm.

- Công cụ tương tác với API GitHub .

Tệp JavaScript cũng chứa các tiện ích mạng để truyền dữ liệu và mô-đun hoạt động chính Shai-Hulud. Theo các nhà nghiên cứu, worm bắt đầu hoạt động bằng cách thu thập thông tin về hệ điều hành của nạn nhân, đồng thời kiểm tra token npm và token  người dùng GitHub đã được xác thực trong môi trường.

Nếu không có token GitHub hợp lệ, bundle[.]js sẽ tự động kết thúc. Một đặc điểm nổi bật của Shai-Hulud là hầu hết chức năng của nó đều hướng đến các hệ thống Linux và macOS: Hầu như tất cả các hành động độc hại đều được thực hiện riêng trên các hệ thống này, ngoại trừ việc sử dụng TruffleHog để tìm kiếm secret.

Bí mật xâm nhập

Sau khi vượt qua các bước kiểm tra, phần mềm độc hại sử dụng token đã đề cập trước đó để lấy thông tin về người dùng GitHub hiện tại. Sau đó, nó chạy hàm extraction, tạo một tập lệnh bash tạm thời /tmp/processor[.]sh và chạy nó như một tiến trình riêng biệt, truyền token làm đối số. Hình 1 là hàm extraction, với các chuỗi và tên biến đã được sửa đổi vì thực tế mã nguồn gốc không thể đọc được.

Hình 1. Chức năng trích xuất, được định dạng lại để dễ đọc hơn

Tập lệnh bash có chức năng giao tiếp với API GitHub và thu thập secret từ kho lưu trữ của nạn nhân theo một cách không thông thường. Đầu tiên, tập lệnh kiểm tra xem token có đủ quyền cần thiết để tạo nhánh và hoạt động với GitHub Actions hay không. Nếu có, tập lệnh sẽ nhận danh sách tất cả các kho lưu trữ mà người dùng có thể truy cập từ 2025.

Trong mỗi nhánh như vậy, tập lệnh tạo một nhánh mới có tên shai-hulud và tải lên shai-hulud-workflow[.]yml, đây là tệp cấu hình để mô tả workflow của GitHub Actions. Các tệp này được tự động hóa và kích hoạt trong GitHub Actions bất cứ khi nào có thay đổi đối với kho lưu trữ.

Hình 2. Cấu hình workflow độc hại

Tệp này thu thập thông tin secret từ kho lưu trữ của nạn nhân và chuyển tiếp đến máy chủ của kẻ tấn công. Trước khi gửi, dữ liệu này mã hóa hai lần bằng Base64.

Phương pháp thu thập dữ liệu bất thường này được thiết kế để trích xuất một lần các secret từ kho lưu trữ của người dùng. Tuy nhiên, nó không chỉ gây ra mối đe dọa cho nạn nhân Shai-Hulud mà còn cho cả các nhà nghiên cứu thông thường. Nếu tìm kiếm “shai-hulud” trên GitHub, chúng ta có thể thấy rất nhiều kho lưu trữ đã bị worm này xâm nhập.

Hình 3. Kho lưu trữ GitHub bị Shai-Hulud xâm phạm

Sau đó, hàm main của bundle[.]js sẽ yêu cầu danh sách tất cả các tổ chức liên quan đến nạn nhân và chạy một hàm riêng biệt khác. Hàm này cũng chạy một tập lệnh bash, nhưng trong trường hợp này, nó lưu vào /tmp/migrate-repos[.]sh, truyền tên tổ chức, tên người dùng và token làm tham số cho các hoạt động độc hại tiếp theo. Tập lệnh bash tự động di chuyển tất cả kho lưu trữ riêng tư và nội bộ từ tổ chức GitHub được chỉ định sang tài khoản người dùng, biến chúng thành kho lưu trữ công khai. Tập lệnh cũng sử dụng API GitHub để sao chép nội dung của các kho lưu trữ dưới dạng bản sao.

Các nhà nghiên cứu nhận định rằng những hành động này nhằm mục đích đánh cắp mã nguồn tự động, từ các kho lưu trữ riêng tư của các cộng đồng và tổ chức nổi tiếng. Ví dụ, công ty nổi tiếng CrowdStrike đã bị ảnh hưởng bởi làn sóng lây nhiễm này.

Khả năng tự sao chép của worm

Sau khi chạy các thao tác trên GitHub của nạn nhân, hàm main bundle[.]js chuyển sang giai đoạn quan trọng tiếp theo - Tự sao chép. Đầu tiên, tập lệnh lấy danh sách 20 gói được tải xuống nhiều nhất của nạn nhân. Để thực hiện việc này, nó thực hiện truy vấn tìm kiếm với tên người dùng từ token npm đã lấy trước đó: https://registry.npmjs.org/-/v1/search?text=maintainer:{%user_details%}&size=20.

Tiếp theo, với mỗi gói tìm thấy nó sẽ gọi hàm updatePackage. Hàm này trước tiên sẽ tải xuống phiên bản tarball của gói (một tệp lưu trữ TAR). Nếu tồn tại, một thư mục tạm thời có tên npm-update-{target_package_name}sẽ được tạo. Phiên bản tarball của gói được lưu tại đó với tên package[.]tgz, sau đó giải nén và chỉnh sửa như sau:

- Gói độc hại bundle[.]js được thêm vào gói ban đầu.

- Một lệnh postinstall thêm vào tệp package[.]json (được sử dụng trong các dự án Node[.]js để quản lý các gói phụ thuộc và metadata dự án). Lệnh này cấu hình để thực thi tập lệnh độc hại thông qua node bundle[.]js.

- Số phiên bản gói được tăng thêm 1.

Gói đã sửa đổi sau đó được đóng gói lại và xuất bản lên npm, dưới dạng phiên bản mới bằng lệnh npm publish. Sau đó, thư mục tạm thời của gói sẽ được xóa.

Hình 4. Hàm updatePackage với định dạng dễ đọc

Tải secret lên GitHub

Hành vi tiếp theo, worm sử dụng tiện ích TruffleHog đã đề cập trước đó để thu thập secret từ hệ thống mục tiêu. Shai-Hulud tải xuống phiên bản mới nhất của tiện ích từ kho lưu trữ gốc cho loại hệ điều hành cụ thể bằng liên kết sau: https://github.com/trufflesecurity/trufflehog/releases/download/{utility version}/{OS-specific file}

Worm này cũng sử dụng các mô-đun của AWS và Google Cloud Platform để dò quét tìm secret. Sau đó, tập lệnh tổng hợp dữ liệu thu thập được thành một đối tượng duy nhất và tạo một kho lưu trữ có tên “Shai-Hulud” trong hồ sơ của nạn nhân. Sau đó, phần mềm độc hại tải thông tin thu thập được lên kho lưu trữ này dưới dạng tệp data[.]json.

Hình 5. Danh sách các định dạng dữ liệu được thu thập từ hệ thống của nạn nhân và tải lên GitHub

Đặc điểm lây nhiễm

Một đặc điểm nổi bật của các gói đã sửa đổi là chúng chứa một kho lưu trữ có tên package[.]tar. Điều này đáng lưu ý vì các gói thường chứa một kho lưu trữ có tên trùng khớp với chính gói đó. Thông qua nghiên cứu, các nhà nghiên cứu đã có thể xác định được gói đầu tiên mà Shai-Hulud bắt đầu lây nhiễm, nhờ vào một điểm khác biệt quan trọng. Như đề cập, sau khi lây nhiễm, một lệnh postinstall để thực thi tập lệnh độc hại node bundle.js, được ghi vào tệp package[.]json.

Lệnh này thường chạy ngay sau khi cài đặt. Tuy nhiên, các nhà nghiên cứu phát hiện rằng một trong những gói bị lây nhiễm đã liệt kê cùng một lệnh như lệnh preinstall, nghĩa là nó chạy trước khi cài đặt. Gói này là ngx-bootstrap phiên bản 18[.]1[.]4. Kaspersky nhận định đây là điểm khởi đầu cho sự lây nhiễm của phần mềm độc hại này. Giả thuyết càng được củng cố bởi thực tế là tên kho lưu trữ trong phiên bản bị nhiễm đầu tiên của gói này khác với tên đặc trưng của các gói bị nhiễm sau đó (package[.]tar).

Khi điều tra các gói khác nhau, các nhà nghiên cứu nhận thấy trong một số trường hợp, một gói chứa nhiều phiên bản độc hại. Điều này có thể xảy ra vì mã độc đã lây lan sang tất cả người bảo trì và đóng góp cho các gói, sau đó mã độc được đưa vào từ mỗi tài khoản của họ.

Thư viện bị nhiễm

Worm Shai-Hulud đã lây nhiễm nhiều thư viện phổ biến mà các tổ chức và nhà phát triển sử dụng hàng ngày, với hơn 500 gói phần mềm phổ biến trong những ngày gần đây, bao gồm cả các thư viện từ công ty CrowdStrike.

Trong số các thư viện bị nhiễm có:

- @crowdstrike/commitlint phiên bản 8[.]1[.]1, 8[.]1[.]2.

- @crowdstrike/falcon-shoelace phiên bản 0[.]4[.]1, 0[.]4[.]2.

- @crowdstrike/foundry-js phiên bản 0[.]19[.]1, 0[.]19[.]2.

- @crowdstrike/glide-core phiên bản 0[.]34[.]2, 0[.]34[.]3.

- @crowdstrike/logscale-dashboard phiên bản 1[.]205[.]1, 1[.]205[.]2.

- @crowdstrike/logscale-file-editor phiên bản 1[.]205[.]1, 1[.]205[.]2.

- @crowdstrike/logscale-parser-edit phiên bản 1[.]205[.]1, 1[.]205[.]2.

- @crowdstrike/logscale-search phiên bản 1[.]205[.]1, 1[.]205[.]2.

- @crowdstrike/tailwind-toucan-base phiên bản 5[.]0[.]1, 5[.]0[.]2.

Nhưng sự kiện thu hút sự chú ý đáng kể đến mối đe dọa đang lan rộng này là vụ lây nhiễm thư viện @ctrl/tinycolor, với hơn hai triệu người dùng tải xuống mỗi tuần.

Phòng ngừa và bảo vệ

Trước mối đe dọa Shai-Hulud và các nguy cơ tương tự, các nhà nghiên cứu khuyên nghị người dùng cá nhân và tổ chức nên thực hiện các biện pháp sau trên toàn bộ hệ thống và cơ sở hạ tầng của mình:

- Sử dụng giải pháp bảo mật đáng tin cậy để tiến hành quét toàn bộ hệ thống.

- Kiểm tra kho lưu trữ GitHub tên shai-hulud.

- Kiểm tra log GitHub Actions để tìm chuỗi có chứa shai-hulud.

- Phát hành lại token npm và GitHub, khóa đám mây (đặc biệt đối với AWS và Google Cloud Platform) và luân phiên các secret khác.

- Xóa bộ nhớ đệm và kiểm kê các mô-đun npm: Kiểm tra các mô-đun độc hại và khôi phục lại phiên bản sạch.

- Kiểm tra các dấu hiệu xâm phạm, chẳng hạn như tệp trong hệ thống, dịch vụ hoặc hiện tượng bất thường khác trong hệ thống mạng.

Để lại bình luận