TL; DR
Một nhà phát hành npm duy nhất đã cung cấp tám gói nhỏ có tên gọi giống như những khối xây dựng thông thường trong phát triển blockchain và ví điện tử. base58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpersvà crypto-validate-libMỗi mô-đun đều chứa một tiện ích hoạt động. Tuy nhiên, sau tiện ích đó là một khối mã tự gọi, chạy ngay khi mô-đun được nhập.
Khoảng 37 giây sau khi nhập khẩuKhối lệnh đó giải mã một dữ liệu được vận chuyển bên trong gói hàng dưới dạng một thiết bị kiểm thử, ghi dữ liệu đó vào một tệp ẩn trong thư mục chính của người dùng, và tự đăng ký để khởi động lại mỗi khi có sự cố. login Trên cả Windows, macOS và Linux, chương trình sẽ khởi chạy tập lệnh đã giải mã dưới dạng một tiến trình độc lập. Không có gì xảy ra trong quá trình cài đặt npm; nó chờ mã được nhập và chạy, đây là một khoảnh khắc yên tĩnh hơn so với quá trình cài đặt.
Dữ liệu tải trọng không bị che khuất. Nó được gửi dưới dạng base64 thuần túy, vì vậy việc giải mã "test fixture" sẽ khôi phục đầy đủ giai đoạn thứ hai: một ví tiền điện tử và kẻ đánh cắp bí mật Chương trình chờ máy ở trạng thái rảnh rỗi, thu thập các khóa riêng và cụm từ hạt giống, mã hóa từng khóa tìm được bằng khóa RSA-4096 được mã hóa cứng, và trích xuất chúng bằng cách ghim vào bộ nhớ IPFS công cộng, gửi tín hiệu trở lại sau mỗi 12 giờ.
Chúng tôi theo dõi cụm này như sau: Đồng bộ ảoTại thời điểm phân tích, cả tám gói đều đã được đăng tải trên kho lưu trữ npm, được xuất bản dưới cùng một tài khoản.
| Hệ sinh thái | NPM |
| Gói | base58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, crypto-validate-lib |
| Các nền tảng được nhắm mục tiêu | Windows, macOS, Linux |
| Hành vi cốt lõi | Trình cài đặt tạm thời được ẩn dưới dạng thiết bị kiểm thử; cài đặt khả năng lưu trữ dữ liệu đa nền tảng. |
| Khối hàng | Phần mềm đánh cắp ví tiền điện tử và bí mật, mã hóa RSA-4096, đánh cắp dữ liệu thông qua cơ chế ghim IPFS công khai. |
Giải phẫu tấn công
Thoạt nhìn, mỗi bao bì đều không có gì đặc biệt. tiện ích base58Ví dụ, đó là một vài kilobyte mã hỗ trợ Base58/Bitcoin-WIF không phụ thuộc vào bất kỳ thư viện nào — đúng như tên gọi của nó. Đoạn mã liên quan nằm ở... sau khi của mô-đun module.exports, nơi mà người đọc chỉ lướt qua đầu tập tin khó có thể để ý đến: một hàm tự gọi tự lên lịch chạy bằng bộ hẹn giờ.
Chuỗi thao tác, được tái tạo từ mã nguồn gói phần mềm, diễn ra như sau:
1. Package is required() by the host project 2. A self-invoking function schedules a callback ~37,000 ms later (setTimeout) 3. On fire, the callback reads test/fixtures/keypairs.dat (a base64 blob) 4. It base64-decodes that blob into a Node.js script 5. It writes the script to ~/.cache-db/.node-sync/syncd.js (mode 0o700) 6. It installs login-persistence for that script (see below) 7. It spawns "node syncd.js" as a detached process Có hai lựa chọn thiết kế nổi bật.
Vật tải được vận chuyển như một thiết bị thử nghiệm. Giai đoạn thứ hai không được viết dưới dạng mã rõ ràng. Nó nằm ở... test/fixtures/keypairs.dat, một tập tin base64 có tên được lồng ghép vào một gói phần mềm tuyên bố xử lý các cặp khóa. Đối với người dùng chỉ cần lướt qua tập tin nén, nó trông giống như dữ liệu mẫu; đối với đoạn mã được thêm vào, nó là một kịch bản cần được giải mã và chạy. Bản thân phần mềm phát tán không chứa địa chỉ mạng — những địa chỉ đó nằm ở giai đoạn thứ hai — nhưng không có thêm bất kỳ sự che giấu nào khác: phần mềm chỉ có một lớp base64 duy nhất, vì vậy việc giải mã nó (base64 -d) khôi phục hoàn toàn syncd.js và hành vi mạng của nó. Phần tiếp theo sẽ trình bày chi tiết về những gì giai đoạn phục hồi đó thực hiện.
Việc kích nổ bị trì hoãn và liên quan đến quá trình nhập khẩu, chứ không phải quá trình lắp đặt. Vì yếu tố kích hoạt là yêu cầu () Thêm vào đó, sử dụng bộ hẹn giờ ~37 giây thay vì một hook cài đặt, hành vi này sẽ bỏ qua các kiểm tra chỉ theo dõi... NPM cài đặt Bước này khiến độ trễ kéo dài hơn nhiều lần chạy thử nghiệm và CI ngắn hạn. Đến khi bất kỳ thứ gì được thực thi, quá trình cài đặt đã tải gói xuống từ lâu đã hoàn tất.
Sau khi kịch bản đã được giải mã và lưu vào ổ đĩa tại ~/.cache-db/.node-sync/syncd.js — một đường dẫn được chọn để hoạt động như một thư mục bộ nhớ đệm thông thường — trình cài đặt đảm bảo nó vẫn hoạt động sau khi khởi động lại trên cả ba nền tảng chính:
- Linux: Một mục cron dùng để khởi chạy lại tập lệnh. Mục này được cài đặt bằng cách lọc crontab hiện có thông qua... grep -v syncdĐiều này dẫn đến tác dụng phụ là loại bỏ mục mới khỏi danh sách thông thường khi tìm kiếm cùng tên.
- Windows: một tác vụ theo lịch trình có tên WinNodeSync, được thiết lập để chạy lại sau mỗi 12 phút.
- hệ điều hành Mac: một tác vụ launchd được gắn nhãn com.apple.syncdCó mặt trong một số gói sản phẩm — một nhãn dán bắt chước dịch vụ hệ thống chính thức của Apple.
Sau đó, tập lệnh được khởi chạy ngay lập tức như một tiến trình độc lập, do đó nó tiếp tục chạy sau khi chương trình nhập dữ liệu kết thúc.
Giai đoạn thứ hai làm gì?
Vì cấu trúc chỉ gồm một lớp base64 duy nhất, giai đoạn thứ hai được giải mã một cách trơn tru và có thể đọc được toàn bộ. Tất cả tám gói đều mang một trong ba biến thể của cùng một kịch bản, tự nhận dạng trong phần chú thích tiêu đề là phantom syncd v3 — topo durmiente ("chuột chũi ngủ"). Nhiệm vụ của nó là đánh cắp dữ liệu ví tiền điện tử và bí mật của nhà phát triển rồi chuyển chúng ra khỏi máy. Nó hoạt động theo các bước sau:
- 1. Chờ đến khi máy ở trạng thái rảnh rỗi. Trước khi làm bất cứ điều gì, syncd.js Hệ thống kiểm tra thời gian người dùng không hoạt động và chỉ tiếp tục khi vượt quá ngưỡng nhất định (khoảng 15 phút) — xprintidle trên Linux, ioreg HIDIdleTime trên macOS và truy vấn thời gian nhàn rỗi bằng PowerShell trên Windows. Do đó, việc thu thập dữ liệu thường diễn ra khi không có ai ngồi trước máy tính.
- 2. Lấy công tắc kích hoạt điều khiển từ xa.. Đoạn mã sẽ lấy một cấu hình nhỏ từ một điểm lưu trữ bí mật trước khi thực hiện. Nguồn chính là URL thô của một đoạn mã trên GitHub (gist.githubusercontent.com/juang55/…/cfg.txt); tập lệnh chỉ được kích hoạt nếu cấu hình đó có nội dung như sau: hoạt động=1Nếu không có thông tin cốt lõi, hệ thống sẽ sử dụng ba mã định danh nội dung IPFS được mã hóa cứng, được lấy thông qua các cổng công cộng. gateway.pinata.cloud, ipfs.iovà cloudflare-ipfs.comĐiều này giúp người vận hành có thể điều khiển việc kích hoạt/vô hiệu hóa vũ khí sau khi sự việc xảy ra và có phương án dự phòng chống bị vô hiệu hóa. (Phiên bản nhỏ nhất, được vận chuyển trong...) thư viện xác thực mã hóa, eth-wallet-helpersvà solana-key-utils(Đã loại bỏ lớp cốt lõi và chỉ dựa vào các định danh IPFS.)
- 3. Thu thập vật liệu và thông tin bí mật của ví. Đoạn mã này sẽ duyệt qua thư mục chính của người dùng — ~/.config/solana, ~/.ethereum/keystore, ~/.foundry, ~/.hardhat, ~ / .sshvà Máy tính để bàn/Tài liệu/Tải Tài Liệu (bao gồm cả tên thư mục bằng tiếng Tây Ban Nha), cộng thêm ~/.env và các tệp rc của shell, và những thứ tương đương AppData các vị trí trên Windows. Nó nhắm mục tiêu vào các khóa riêng tư Ethereum, khóa WIF Bitcoin, cụm từ hạt giống BIP-39, cặp khóa Solana, JSON kho khóa Ethereum, khóa SSH và các biến môi trường chứa thông tin bí mật. Biến thể lớn hơn (trong mã hóa abi, tiện ích base58, eth-dev) chứa toàn bộ từ điển BIP-39 gồm 2048 từ và sử dụng biểu thức chính quy để trích xuất các khóa riêng lẻ và các cụm từ hạt giống đã được xác thực từ bất kỳ văn bản nào mà nó đọc; hai biến thể nhỏ hơn thì khớp các tệp theo từ khóa (hạt giống, ghi nhớ, ví, metamask, ma, sổ cái, trezor, …) và tải lên toàn bộ tập tin.
- 4. Mã hóa và trích xuất dữ liệu thông qua dịch vụ mã hóa công khai. Mỗi phát hiện đều đi kèm với dấu vân tay của vật chủ (tên người dùng@tên máy chủ(nền tảng, dấu thời gian) và được mã hóa bằng khóa công khai RSA-4096 được nhúng sẵn trong tập lệnh. Bản ghi được mã hóa sau đó được tải lên bằng cách ghim nó vào IPFS thông qua api.pinata.cloud/pinning/pinJSONToIPFSĐược xác thực bằng thông tin đăng nhập API Pinata được mã hóa cứng. Không có máy chủ C2 chuyên dụng nào để chiếm giữ: dữ liệu bị đánh cắp được lưu trữ trong kho lưu trữ phi tập trung công cộng, có thể được người điều hành truy xuất bằng cách sử dụng các hàm băm nội dung thu được. Quá trình tải lên được thực hiện cách nhau vài giây với độ lệch ngẫu nhiên, và nhật ký cục bộ của... dấu thời gian | loại khóa | mã băm trả về được giữ tại ~/.cache-db/.node-sync/.sl.
- 5. Duy trì hoạt động và phát tín hiệu theo chu kỳ 12 giờ. Giai đoạn thứ hai thiết lập lại tính bền vững của chính nó — một mục nhập cron trên Linux, một com.apple.syncd Tác vụ launchd trên macOS và một tác vụ theo lịch trình có tên WindowsNodeSync Trên Windows — được thiết lập để chạy lại sau mỗi 12 giờ. Lưu ý đây là một khác nhau Tên tác vụ Windows từ tác vụ mà trình cài đặt dropper thực hiện (WinNodeSyncCả hai đều đáng để tìm kiếm.
Lịch Trình Sự Kiện
Tám gói phần mềm này được phát hành liên tiếp vào ngày 13 và 14 tháng 7 năm 2026. Một số gói có nhiều hơn một phiên bản; trình thả tệp giống hệt nhau giữa các phiên bản, chỉ có vị trí dòng thay đổi khi kích thước của mã tiện ích lành tính phía trên nó thay đổi.
| Ngày | Sự kiện |
|---|---|
| 2026-07-13 | Các gói đầu tiên trong cụm xuất hiện dưới một nhà xuất bản (solana-key-utils, eth-wallet-helpers, crypto-validate-lib và các phiên bản đầu tiên của những thứ còn lại) |
| 2026-07-13 → 07-14 | Các tên còn lại và các phiên bản tiếp theo đã được xuất bản; các tàu thả hàng kèm theo giống nhau trong mỗi phiên bản. |
| 2026-07-14 | Cả tám gói đều được gắn cờ và phân tích; mỗi gói vẫn có thể cài đặt được từ registry. |
Trong suốt đợt bùng phát, uy tín của nhà phát hành trên hệ thống đăng ký đã chuyển từ mức trung lập vào đầu đợt sang mức tiêu cực mạnh khi số lượng phát hiện tăng lên — đây là một tác dụng phụ có thể quan sát được do các gói phần mềm bị gắn cờ, chứ không phải là một tính năng được thiết kế.
Các chỉ số về sự thỏa hiệp
Tất cả các chỉ số dưới đây đều được xác nhận có mặt tại thời điểm phân tích — những chỉ số trong bảng “Giai đoạn thứ hai” bằng cách giải mã. test/fixtures/keypairs.dat và đọc những gì đã được phục hồi syncd.js.
Tệp và đường dẫn
| chỉ số | Vai trò |
|---|---|
~/.cache-db/.node-sync/syncd.js | Giai đoạn giải mã thứ hai, được ghi bằng chế độ 0o700 |
~/.cache-db/.node-sync/.sl | Nhật ký rò rỉ dữ liệu cục bộ (dấu thời gian | loại khóa | mã băm IPFS) |
test/fixtures/keypairs.dat | Dữ liệu được mã hóa Base64 được lưu trữ bên trong tệp nén tarball như một "công cụ thử nghiệm". |
Cơ sở hạ tầng mạng giai đoạn hai (được khôi phục từ syncd.js)
| chỉ số | Vai trò |
|---|---|
gist.githubusercontent.com/juang55/b298754cb72942b1cdcf02ccd45cde2f/raw/cfg.txt | Kích hoạt bằng phương pháp bỏ rơi tự động; tập lệnh chỉ chạy nếu cấu hình đọc được. active=1 |
Qmcqz3w8j4qFQXDAXAxnrdc2oSX3nzBT4NqtpTqL8mr1ga | Cấu hình dự phòng IPFS (CID) |
QmdTXoqVmTHY1i4ZWLdLkoQ9YChp5TXPh5cWXwnAYZt5iF | Cấu hình dự phòng IPFS (CID) |
QmfJkLU5gdCpqbbqEjWYC2anXW9FmuEeSLLeLiHVJKYUjp | Cấu hình dự phòng IPFS (CID) |
gateway.pinata.cloud, ipfs.io, cloudflare-ipfs.com | Các cổng IPFS được sử dụng để lấy cấu hình dự phòng. |
api.pinata.cloud/pinning/pinJSONToIPFS | Điểm cuối trích xuất dữ liệu, dữ liệu bị đánh cắp được ghim vào IPFS công cộng. |
| Khóa API Pinata | 13c766575b9270a9825dThông tin xác thực rò rỉ được mã hóa cứng |
Các mục tiêu thu thập giai đoạn thứ hai (được khôi phục từ syncd.js)
| chỉ số | Vai trò |
|---|---|
~/.config/solana, ~/.ethereum/keystore, ~/.foundry, ~/.hardhat, ~/.ssh, ~/.envcác tệp rc shell | Các thư mục/tệp tin được tìm kiếm để lấy khóa và thông tin bí mật |
AppData\Roaming\Solana, AppData\Local\ethereum\keystore | Đã tìm kiếm các phiên bản tương đương của Windows |
| Các loại hiện vật được thu hoạch | Khóa riêng tư ETH, Bitcoin WIF, cụm từ hạt giống BIP-39, cặp khóa Solana, JSON kho khóa Ethereum, khóa SSH, biến môi trường bí mật |
Các hiện vật bền vững
| Nền tảng | chỉ số |
|---|---|
| Linux | Khởi chạy mục nhập cron syncd.js; được cài đặt thông qua crontab, được lọc qua grep -v syncd |
| Cửa sổ | nhiệm vụ theo lịch trình WinNodeSync (ống nhỏ giọt) và WindowsNodeSync (giai đoạn thứ hai) |
| macOS | nhãn launchd com.apple.syncd |
| Tất cả | Giai đoạn thứ hai lặp lại theo chu kỳ 12 giờ. |
Hành vi
- Hàm tự gọi được thêm vào sau module.exports, lên lịch cho một setTimeout Khoảng 37,000 ms khi nhập dữ liệu.
- tiến trình con sinh ra(“nút”, ) với bộ tùy chọn tách rời.
- Kích hoạt bằng cơ chế chờ ở giai đoạn thứ hai (xprintidle / ioreg HIDIdleTime / Thời gian nhàn rỗi của PowerShell; ngưỡng ~15 phút).
- Tìm kiếm mã hóa RSA-4096, sau đó là HTTPS. POST đến một API ghim IPFS công khai.
Các gói và phiên bản (npm, nhà xuất bản solbuilder_io)
| Bưu kiện | Các phiên bản |
|---|---|
base58-utils | 1.0.0, 1.0.1, 1.0.3 |
abi-encode | 1.0.0, 1.0.1, 1.0.2 |
eth-dev | 1.0.0, 1.0.1, 1.0.2 |
arb-kit | 1.0.0, 1.0.1 |
layer2-sdk | 1.0.0, 1.0.1 |
solana-key-utils | 1.0.0 |
eth-wallet-helpers | 1.0.0 |
crypto-validate-lib | 1.0.0 |
Nhà xuất bản
- solbuilder_io - angel_lopez89[@]proton[.]meEmail chưa được xác minh, không có tài khoản kiểm soát nguồn đã được xác minh, không có kho lưu trữ được liên kết.
Sự quy kết và hành vi quan sát được
Tám gói phần mềm này dùng chung một tài khoản nhà xuất bản và một nội dung tải. Mỗi gói đều là một gói đơn giản — vài kilobyte mã tiện ích thực sự với cùng một trình thả được gắn kèm — được xuất bản mà không có kho lưu trữ liên kết và dưới một địa chỉ email kiểu dùng một lần chưa được xác minh. Sự đồng nhất đó, đường dẫn thả chung, nhãn duy trì chung và... keypairs.dat Các tập tin dàn dựng là yếu tố liên kết các cụm máy chủ lại với nhau.
Các gói hàng này thể hiện sự thẳng thắn bất thường về hành vi của chính chúng. solana-key-utils chứa các bình luận nội tuyến mô tả khối được thêm vào bằng ngôn ngữ đơn giản — một bình luận ghi nhãn cho nó. BÓNG MA: sự dai dẳng vô hìnhMột đoạn khác (bằng tiếng Tây Ban Nha) có nội dung như sau: Ejecutar topo en background, “chạy chương trình con chuột chũi trong nền.” Đây là những chú thích của chính mã nguồn về những gì nó làm; tên chiến dịch trong bài đăng này được lấy từ nhãn đầu tiên đó cùng với nút giả “sync daemon” (đồng bộ hóa) mà bộ máy duy trì bắt chước.
Chúng tôi chỉ mô tả những gì mã nguồn thực hiện một cách rõ ràng. Việc đặt tên các gói phần mềm — toàn bộ đều là các thuật ngữ về mật mã, ví điện tử và công cụ blockchain — cho thấy đối tượng nhà phát triển nào có khả năng sẽ sử dụng chúng; bản thân việc đặt tên không xác định được ai là nhà phát hành. Giai đoạn thứ hai hoàn toàn có thể khôi phục được bằng cách giải mã đoạn mã base64, và hành vi của nó được mô tả ở trên: nó thu thập các khóa ví, cụm từ hạt giống và bí mật, sau đó trích xuất chúng, được mã hóa RSA, vào bộ nhớ IPFS công cộng thông qua Pinata. Một lựa chọn thiết kế đáng chú ý là sự vắng mặt của máy chủ C2 riêng — cấu hình được lấy từ một gist trên GitHub và IPFS, và dữ liệu bị đánh cắp được lưu trữ trong bộ nhớ phi tập trung công cộng được khóa bằng hàm băm nội dung, cả hai đều khó thu giữ hơn so với một máy chủ do kẻ tấn công kiểm soát. Tại thời điểm viết bài này, không tìm thấy báo cáo công khai nào trước đó phù hợp với cụm tấn công này.
Tác động, xu hướng và hướng dẫn dành cho người bảo vệ
Ai bị lộ thông tin? Bất kỳ ai đã thêm một trong những gói này vào dự án Node và sau đó chạy mã nhập gói đó đều có thể bị ảnh hưởng. Vì quá trình kích hoạt diễn ra trong quá trình nhập chứ không phải cài đặt, nên chỉ cần gói đó hiện diện là chưa đủ — mà bất kỳ thao tác sử dụng thông thường nào tải mô-đun đều có thể dẫn đến việc bị tấn công. Tên mồi nhử nhắm mục tiêu vào các nhà phát triển xây dựng trên Ethereum, Solana, Arbitrum, Layer-2 và các công cụ ví/mã hóa nói chung — nhóm người có nhiều khả năng sở hữu chính xác các tài sản mà giai đoạn thứ hai đang tìm kiếm. Bất kỳ ai đã chạy một trong những mô-đun này trên máy tính chứa khóa ví, cụm từ hạt giống, kho khóa, khóa SSH hoặc .NS Các công ty bảo mật nên coi những thông tin đăng nhập đó là đã bị xâm phạm và thay đổi chúng liên tục.
Hai mô hình đáng để ghi nhớ. Đầu tiên, tải trọng như một vật cố định: vận chuyển giai đoạn thứ hai dưới dạng base64 bên trong một tệp dữ liệu có tên hợp lý (test/fixtures/keypairs.dat) giữ cho nguồn gốc hiển thị của gói phần mềm trông sạch sẽ và đẩy nội dung độc hại vào một tệp mà các công cụ kiểm tra và người dùng thường coi là dữ liệu không hoạt động. Thứ hai, Thực thi trì hoãn tại thời điểm nhập với khả năng lưu trữ đa nền tảngViệc di chuyển trình kích hoạt ra khỏi hook cài đặt, thêm bộ hẹn giờ, và sau đó duy trì trạng thái đó xuyên suốt cron, các tác vụ theo lịch trình và launchd là một bước đi có chủ đích nhằm tránh xa các kỹ thuật kịch bản cài đặt ồn ào mà quá trình quét registry tự động thường theo dõi sát sao nhất.
Hướng dẫn dành cho người bảo vệ và người duy trì:
- Xử lý đoạn mã được thêm vào sau module.exports Ưu tiên xem xét — logic của dropper thường ẩn bên dưới bề mặt "thực" của module.
- Đừng cho rằng các tập tin dữ liệu là vô tri vô giác. Một khối dữ liệu base64 nằm dưới... kiểm tra/thiết bị/ được đọc trong quá trình chạy và được giải mã là liền kề với tệp thực thi; đánh dấu các lần đọc trong quá trình chạy của các tệp dữ liệu mẫu cung cấp cho một Chức năng/đánh giá/viết-sau đó-sinh sản chuỗi.
- Tìm đường rơi xuống ~/.cache-db/.node-sync/ và cho các đơn vị lưu trữ WinNodeSync (nhiệm vụ theo lịch trình) và com.apple.syncd (launchd) trên các máy của nhà phát triển đã lấy những tên này.
- Cảnh báo về các tiến trình Node tạo ra các mục cron, tác vụ theo lịch trình hoặc công việc launchd — các thư viện hợp lệ hiếm khi làm điều này khi nhập khẩu.
- Nên ưu tiên sử dụng lockfile và pinned version, và xem lại sự khác biệt (diff) của bất kỳ phụ thuộc "tiện ích" nhỏ nào mới, đặc biệt là... các gói không phụ thuộc đã được xuất bản Được đăng tải bởi các tài khoản chưa được xác minh và không có kho lưu trữ liên kết.
Đối với những người bảo vệ registry, điều cần lưu ý là việc giám sát hook cài đặt là cần thiết nhưng chưa đủ: một dropper được cài đặt trong quá trình nhập dữ liệu và bị trì hoãn bởi bộ hẹn giờ, nằm bên trong một tệp dữ liệu, sẽ vượt qua được bước kiểm tra chỉ diễn ra trong quá trình cài đặt, và bước duy trì thường là tín hiệu rõ ràng nhất còn lại cần phải nắm bắt.



