TL; DR
Inter la 1-a de aprilo kaj la 3-a de majo 2026, unu sola npm-eldonisto, user0001, registrita per la nekonfirmita Gmail-adreso tanvisoul9@gmail.com, kviete puŝis ses pakaĵojn kun intence banalaj, infrastruktur-sonantaj nomoj: centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtimeKaj node-env-resolve.
La du plej novaj versioj de node-env-resolve, 1.0.7 kaj 1.0.8, estis markitaj de la sistemo Malica Programaro Frua Averto (MEW) de Xygeni la 2-an de majo kaj konfirmitaj kiel malicaj la 3-an de majo.
La enplantaĵo estas nekutima pro tio, kio ĝi ne estas: ne estas Telegram-robotoj, nek OAST-revokoj, nek malhelpo, kaj neniu provo akiri AWS-akreditaĵojn dum instalado. Anstataŭe, postinstall.js plantas Vindozan start-persistan eniron, uzante HKCU-Kun-ŝlosilon kiu lanĉas wscript.exe kontraŭ VBS-stumpo. Poste ĝi kreas dekroĉitan Node.js-agenton, kiu kunigas modulojn por mikrofona kapto, ŝtelo de retumil-historio, ekranfotoj kaj muso/klavara simulado.
Ni nomas ĉi tiun areton DevTap, post la ilaro ĝi lasas funkcii sur la maŝino de programisto.
Ĉiuj ses pakaĵoj estis disponeblaj ĉe npm dum la verkado de ĉi tio. Ni sendis ilin al la misuza kanalo de la registro. Defendantoj devus forigi ĉiujn instalojn de la eldonisto atendante forigon.
La Areto: Ses Pakaĵoj, Unu Eldonisto
La eldonista konto user0001 estas nekonfirmita. Ĝi ne havas SCM konfirmo, neniu retpoŝtadreso ligita al domajno, kaj neniu antaŭa historio. La Gmail-uzanto tanvisoul9 ne aperas en iu ajn alia npm-eldonista registro, kiun ni povis trovi.
Ĉiuj ses pakaĵoj listigas la saman prizorgiston, estis publikigitaj de la sama konto, kaj dividas la saman package.json ŝablono. Ne ekzistas repository, ne homepage, kaj ne description pli longa ol unu sola linio.
La nomstrategio estas la interesa parto. Male al klasika dependec-konfuza aŭ tajperar-skvaĉa kampanjo, neniu el ĉi tiuj nomoj celas specifan antaŭan bibliotekon. Anstataŭe, ili estas kalibritaj por malaperi en realan package.json or npm ls eligo.
| pakaĵo | Unue Eldonita | Plej lasta versio | versioj | Rolo en la Areto |
|---|---|---|---|---|
| centralogger | 2026-04-01 12:46 UTC | 1.0.9 | 5, de 1.0.5 ĝis 1.0.9 | Kovrilo de la "protokolada ilo" de la areto; plej frua publikigo |
| dom-utils-lite | 2026-04-14 07:36 UTC | 1.0.3 | 3 | Ĝenerala DOM-helpanto kovrilo |
| nodo-alporto-malpeza | 2026-04-19 10:22 UTC | 1.0.2 | 3 | Imitas nod-alportan familion |
| konektilo-agento | 2026-04-25 05:12 UTC | 1.0.0 | 1 | Ĝenerala nomo "agento" |
| nodo-gyp-rultempo | 2026-04-25 05:17 UTC | 1.0.0 | 1 | Imitas ilojn por konstrui denaskajn modulojn |
| nodo-medio-solvi | 2026-04-25 05:21 UTC | 1.0.9 | 10, de 1.0.0 ĝis 1.0.9 | Aktiva gutigilo; plena enplantaĵo |
Nomoj kiel centralogger, node-fetch-liteKaj node-gyp-runtime estas desegnitaj por aspekti nekontestataj dum kodrevizio. Ili sonas kiel aferoj, kiuj jam estus en la dependecarbo de projekto.
Kombinite kun freŝa, nekonfirmita eldonisto kaj mankantaj ligiloj al deponejo, ili formas rekoneblan ŝablonon: aktoro semanta malalt-frikciajn nomojn en la registron, poste ripetante rapide sur tiu, kiu gravas. En ĉi tiu kazo, node-env-resolve ricevis dek versiojn en ok tagoj.
Kio Alteriĝas sur Vindoza Dev-Skatolo
La malica ĉeno sur node-env-resolve:1.0.8 estas mallonga, rekta, kaj nekutime trajtoriĉa por npm RAT.
Postinstalo: Persisto kaj Malligita Agento
package.json deklaras unuopan instal-hokon:
{ "scripts": { "postinstall": "node postinstall.js" } }postinstall.js faras tri aferojn laŭorde.
Unue, ĝi prezentas instalaĵan dosierujon ekster la npm-arbo. La pado estas kalkulata dum rulado en la skripto kiel INSTALL_DIR. Tiam ĝi efektivigas internan execSync('npm install --production --silent ...') en ĝi por tiri la rultempajn dependecojn de la enplantaĵo. Tio metas la agenton sur diskon ie mana node_modules revizio ne trovos.
Due, ĝi skribas VBS-lanĉilon kaj registras ĝin por startpersisto:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run \ /v ${AGENT_NAME} \ /t REG_SZ \ /d "wscript.exe \"${vbsPath}\"" /fwscript.exe estas la Windows Script Host, subskribita Microsoft-duuma dosiero kiu funkcias .vbs dosierojn sen konzola fenestro. Tio estas antaŭecistial ĝi estas preferata por aŭtomataj rulaj stuboj.
Ankaŭ ekzistas kongruo reg delete vojo interne src/index.js, sugestante ke la enplantaĵo estas desegnita por esti pure forprenebla laŭ la komando de la funkciigisto.
Trie, ĝi kreas apartan infanprocezon:
spawn(node, [path.join(INSTALL_DIR, 'src/index.js')], { detached: true, env: { ...process.env, SERVER_URL } })Du detaloj gravas ĉi tie.
SERVER_URL estas legita el la ĉirkaŭaĵo. Rezulte, la C2-finpunkto estas agordebla laŭ deplojo kaj ne estas enigita en la pakaĵon. Tiu malgranda sed konscia elekto venkas plej multajn statikajn IOC-svingojn.
Ankaŭ, la generita infano heredas la plenan gepatran medion. Tial, ĉiu NPM_TOKEN, AWS_*, GITHUB_TOKEN, aŭ SSH-agenta ingo ĉeestanta en la programista ŝelo dum instalado vojaĝas en la memoron de la longdaŭra agento.
Kion la agento sendas kun
La faskigita src/ arbo inkluzivas tri modulojn, kies nomoj sole rakontas la historion: audioCapture.js, browserHistory.jsKaj systemInfo.js.
La listo de dependecoj de rultempo, solvita dum la enscenigita npm install, konfirmas ilin.
Ĉi tiu aliro transformas kaosan okazaĵon en kontrolitan respondon.
Anstataŭ reagi blinde, teamoj agas kun klara prioritatigo kaj rapida solvado.
| dependeco | Por kio ĝi estas en ĉi tiu kunteksto |
|---|---|
| ekranfoto-labortablo | Perioda ekrankapto |
| @nut-tree-fork/nut-js | Muso- kaj klavaraŭtomatigo / eniga simulado |
| pli bona-sqlite3 | Rektaj legadoj de SQLite-datumbazoj de Chrome, Edge kaj Firefox History |
| adm-zip | Faskigante kolektitajn artefaktojn antaŭ elfiltrado |
| akra | Regrandigo / kunpremo de ekranfotoj kaj bildaj artefaktoj |
| socket.io-kliento | Persista dudirekta C2-kanalo |
| nodo-maŝino-identigilo | Stabila fingrospuro por ĉiu gastiganto por spurado de viktimoj |
systemInfo.js Nomitaj os.networkInterfaces() por plia fingrospurado antaŭ la unua signostango.
Kial la Aŭdio-Kaptado Estas la Elstara Signalo
Plej multaj npm RAT-oj, kiujn ni triigas en MEW, haltas dum instaltempo dum sekreta ŝtelo. Ili legas ~/.npmrc, legu ~/.aws/credentialsskrapi process.env, sendu POST al retkonektilo, kaj eliru. Tio konvenas al frakas-kaj-kaptu ekonomia modelo. Akreditaĵoj havas mallongan duoniĝotempon, kaj la atakanto bezonas rapide monetigi.
node-env-resolve estas malsama laŭ formo.
La persisto estas agordita por postvivi restartigon. La agento funkcias dekroĉite kaj longdaŭre sub wscript.exeLa ilaro, kiun ĝi portas, estas por esti tie sur la maŝino de programisto, ne por preni kaj lasi: mikrofonregistrilo, pelilo por klavaro/muso, plena enpreno de retumilhistorio, ekrankopio, kaj interaga Socket.IO-kanalo reen al agordebla C2.
Mikrofona kapto aparte estas la limo, kiun ĉi tiu kampanjo transiras, kiun plej multaj npm-malware ne transpasas.
Programista laborstacio estas, pli kaj pli, ankaŭ la laborstacio kie programistoj faras stand-up-intervjuojn, klientvokojn, dezajndiskutojn kaj deĵorajn pontojn. Enplantaĵo kiu registras la mikrofonon ne vere celas la npm-ĵetonon de la programisto. Ĝi celas tion, kion la programisto diras antaŭ la tekokomputilo.
Tiu kapablaro, plus la manko de malklarigo kaj la foresto de iu ajn pompaĉa elfiltrado dum instaltempo, legiĝas kiel antaŭpoziciigado por celita aliro anstataŭ oportunisma ŝtelo de akreditaĵoj.
Ni ne asertas atribuon nur el ĉi tio. Ni notas la funkcian profilon.

La ok-taga iteracia kadenco je node-env-resolve estas la plej funkcie elokventa detalo en la templinio.
Ĉi tio ne estas "forĵetu kaj forgesu"-deplojo. La eldonisto aktive prizorgas la deplojilon, kio kutime signifas unu el du aferoj. Aŭ ili agordas ĝin kontraŭ testaj medioj antaŭ pli vasta deplojo, aŭ ili jam havas instalan telemetrion revenantan kaj respondas al ĝi.
La aliaj kvin pakaĵoj efike ne spertis perdon post sia komenca publikigo. Tio konformas al ŝablono "enmeti unufoje, forlasi nomitan" por la subtena areto, dum inĝeniera penado fokusiĝas al la pakaĵo, kiu faras la laboron.
Atribuo: Malgrandaj Indicoj, Neniu Firma Verdikto
publikajn OSINT signaloj estas maldikaj, kaj ni ne etendos ilin. Kio estas observebla:
La Gmail-adreso tanvisoul9 parte similas al sud-azia persona nomo, "Tanvi". Ĉi tio estas malforta signalo. Gmail-uzantoj ne estas identeco, kaj la fina soul9 estas ĝenerala. Ne estas sekure dedukti geografion nur el loka parto de retpoŝto.
La stilo de la kodo estas ordinara en Node.js: standard bibliotekaj vokoj kiel ekzemple os, child_process, spawnKaj reg addNe estas malklarigado, nek ĉenrotacio, nek kontraŭcimiga logiko. La aŭtoro komfortas kun la primitivoj de la registro de Vindozo kaj la orkestrado de dekroĉitaj infanoj-procezoj, sed ŝajne ne celas pli sekretajn teknikojn, kiujn ili povus kredinde uzi.
Dependecoj estas tute pretaj kaj bone konataj: screenshot-desktop, nut-js, better-sqlite3Kaj socket.io-clientNe ekzistas kutima protokolo, neniu C2-stako de nulo, kaj neniu nova persistemtruko preter lernolibro. HKCU Kuri ŝlosiloĈi tiu estas kompetenta integrilo, ne aŭtoro de iloj.
Ni ne trovis ne-anglajn ĉenojn, enigitajn komentojn, lokajn datumojn, aŭ fingrospurojn de horzonoj elirigitaj de la kompililo ene de la publikigitaj artefaktoj.
Ni kontrolis kodan interkovron kun antaŭaj kampanjoj, kiujn ni jam spuras, inkluzive de Shai-Hulud, Owlivion, Buildkite, kaj la lastatempa hejbai / claude-code-best Anthropic-CLI klona familio. Ni trovis neniun: neniujn komunajn C2-ŝablonojn, neniujn komunajn dosieraranĝojn, kaj neniujn komunajn idiomaĵojn.
Kion ni ne dirus: ke temas pri ŝtata aktoro, konata grupo, aŭ geografie ligita al iu ajn specifa lando.
La funkcia profilo kongruas kun malgranda, modere sperta teamo faranta gvatadon de programistaj laborstacioj. Ĝi estas verŝajne finance motivita per posta uzo de la aliro, sed eble ankaŭ per sciigo kiel servo por aparta aĉetanto.
Du nerektaj punktoj subtenas tion: la evitado de atentkaptaj elfiltraj mekanikoj, kiuj rapide forbruligus la areton, kiel ekzemple Telegram-robotoj, oastify.com, aŭ canarytokens, kaj la intence banalaj pakaĵnomoj, kiuj preferas kvietajn longvostajn instaladojn anstataŭ mallongan altvolumenan pliiĝon.
Indikiloj de Kompromiso kaj Detekto
| Pakaĵoj kaj Eldonisto | |
|---|---|
| Kampo | valoro |
| npm-eldonisto | user0001 |
| Retpoŝto de eldonisto | tanvisoul9@gmail.com, nekonfirmita |
| pakaĵoj | centralogger, dom-utils-lite, node-fetch-lite, konektilo-agento, node-gyp-rultempo, node-env-resolve |
| Konfirmita malica | nodo-medio-solvi@1.0.7, nodo-medio-solvi@1.0.8 |
| Gastigantaj Artefaktoj | |
|---|---|
| tipo | valoro |
| Persista ŝlosilo | HKCU\Software\Microsoft\Windows\CurrentVersion\Run |
| Persista valoro | Variablonomo; datumoj de la formo wscript.exe " \\ .vbs" |
| Instali hokon | postinstalo: nodo postinstall.js en la pakaĵa manifesto |
| Implantaĵaj moduloj | fonto/audioCapture.js, fonto/browserHistory.js, fonto/systemInfo.js |
| Ensceniga dosierujo | INSTALL_DIR solvita ekster la node_modules de la projekto; loko difinita de postinstall.js dum instalado |
| reto | |
|---|---|
| tipo | valoro |
| C2-transporto | socket.io-kliento, persista dudirekta kanalo |
| C2-finpunkto | Provizita al la agento per la ĉirkaŭa variablo SERVER_URL; ne fikse kodita en publikigitajn artefaktojn |
Detektaj Notoj
Du reguloj kaptas ĉi tiun familion sen bezono de la C2-finpunkto.
Unue, marku postinstalajn skriptojn, kiuj plenumas internan npm install en padon ekster la propra dosierujo de la pakaĵo. Ĉiu legitima antaŭkonstrua elŝutilo, kiel ekzemple node-gyp rekonstruas aŭ antaŭkonstruitajn duumajn elŝutilojn, skribas ene de la pakaĵo aŭ en platformon-standard kaŝmemorpadoj kun konfirmitaj haŝoj. Ĝi ne skribas en ĵus kreitan INSTALL_DIR aliloke sur la disko.
Due, marku postinstalajn skriptojn, kiuj havas problemojn reg add HKCU\…\Run kun wscript.exe kiel la lanĉilo. Ĉi tio esence neniam estas legitima el npm-pakaĵo. Flagu kaj kvarantenu ĝin.
Tria heŭristiko utilas por trovi la sekvan fratan pakaĵon antaŭ ol ĝi estas konfirmita: freŝa npm-eldonisto sen SCM konfirmo, retpoŝto de Gmail, ne repository kampo, kaj pluraj mallongaj, ĝeneralaj, infrastruktur-sonantaj pakaĵnomoj publikigitaj ene de tagoj unu de la alia sufiĉas por pravigi manan revizion.
Raportita al la npm-registro. Ni ĝisdatigos ĉi tiun afiŝon kiam la eldonista konto estos forigita.






