Ataque de Typosquatting de DevTap npm

Ataque de typosquatting de DevTap npm: seis paquetes maliciosos teñen como obxectivo as estacións de traballo dos desenvolvedores

TL, RD

Entre o 1 de abril e o 3 de maio de 2026, un único editor de npm, user0001, rexistrado co enderezo de Gmail non verificado tanvisoul9@gmail.com, impulsou discretamente seis paquetes con nomes deliberadamente insípidos que soaban a infraestruturas: centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtimee node-env-resolve.

As dúas últimas versións de node-env-resolve, 1.0.7 e 1.0.8, foron sinaladas polo sistema de alerta anticipada de software malicioso (MEW) de Xygeni o 2 de maio e confirmadas como maliciosas o 3 de maio.

O implante é inusual polo que non é: non hai bots de Telegram, nin chamadas de retorno de OAST, nin ofuscacióne sen ningún intento de obter as credenciais de AWS no momento da instalación. En vez diso, postinstall.js planta unha entrada de persistencia de arranque de Windows, usando unha clave Executar HKCU que inicia wscript.exe contra un stub VBS. Despois, xera un axente Node.js separado que inclúe módulos para a captura de micrófonos, o roubo do historial do navegador, as capturas de pantalla e a simulación do rato/teclado.

Chamamos a este clúster DevTap, despois do kit, sae executándose na máquina dun desenvolvedor.

Os seis paquetes estaban dispoñibles en npm no momento de escribir isto. Enviámolos á canle de abuso do rexistro. Os defensores deberían retirar calquera instalación do editor pendente de eliminación.

O clúster: seis paquetes, un editor

A conta do editor user0001 non está verificado. Non ten SCM verificación, sen correo electrónico vinculado a dominio e sen historial previo. O identificador de Gmail tanvisoul9 non aparece en ningún outro rexistro de editor de npm que puidemos atopar.

Os seis paquetes listan o mesmo responsable do mantemento, foron publicados desde a mesma conta e comparten o mesmo package.json modelo estándar. Non hai ningún repository, non homepage, e non description máis longo que unha soa liña.

A estratexia de nomes é a parte interesante. A diferenza dunha campaña clásica de confusión de dependencias ou typosquat, ningún destes nomes ten como obxectivo unha biblioteca específica augas arriba. En cambio, están calibrados para desaparecer nun mundo real. package.json or npm ls saída.

PaquetePrimeira publicaciónÚltima versiónversiónsRol no clúster
centralogger2026-04-01 12:46 UTC1.0.95, de 1.0.5 a 1.0.9Cuberta da "utilidade de rexistro" do clúster; primeira publicación
dom-utils-lite2026-04-14 07:36 UTC1.0.33Cuberta xenérica de DOM-helper
node-fetch-lite2026-04-19 10:22 UTC1.0.23Familia de busca de nodos Mimics
axente-conector2026-04-25 05:12 UTC1.0.01Nome xenérico "axente"
tempo de execución de nodo-gyp2026-04-25 05:17 UTC1.0.01Ferramentas de compilación de módulos nativos imita
resolución-de-entorno-de-nodos2026-04-25 05:21 UTC1.0.910, de 1.0.0 a 1.0.9Contagotas activo; implante completo

Nomes como centralogger, node-fetch-litee node-gyp-runtime están deseñados para parecer impedíbeis na revisión de código. Soan como cousas que xa estarían na árbore de dependencias dun proxecto.

Combinados cun editor novo e non verificado e ligazóns de repositorio que faltan, forman un patrón recoñecible: un actor que introduce nomes de baixa fricción no rexistro e logo iterando rapidamente no que importa. Neste caso, node-env-resolve recibiu dez versións en oito días.

Que chega a unha caixa de desenvolvemento de Windows

A cadea maliciosa node-env-resolve:1.0.8 é curto, directo e inusualmente rico en funcións para un RAT npm.

Postinstalación: Persistencia e axente desvinculado

package.json declara un único gancho de instalación:

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

postinstall.js fai tres cousas por orde.

Primeiro, prepara un directorio de instalación fóra da árbore npm. A ruta calcúlase no tempo de execución do script como INSTALL_DIRDespois executa unha operación interna execSync('npm install --production --silent ...') dentro del para extraer as dependencias de execución do implante. Isto coloca o axente no disco nalgún lugar manual node_modules a auditoría non atopará.

En segundo lugar, escribe un lanzador VBS e rexístrao para a persistencia de arranque:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run \     /v ${AGENT_NAME} \     /t REG_SZ \     /d "wscript.exe \"${vbsPath}\"" /f

wscript.exe é o Windows Script Host, un binario de Microsoft asinado que se executa .vbs ficheiros sen unha xanela de consola. Iso é previocisely por que se prefire para os stubs de execución automática.

Tamén hai unha correspondencia reg delete camiño interior src/index.js, o que suxire que o implante está deseñado para ser extraíble facilmente por orde do operador.

En terceiro lugar, xera un proceso fillo separado:

spawn(node, [path.join(INSTALL_DIR, 'src/index.js')], {   detached: true,   env: { ...process.env, SERVER_URL } })

Dous detalles importan aquí.

SERVER_URL lése do ambiente. Como resultado, o punto final C2 é configurable por despregamento e non está integrado no paquete. Esta pequena pero deliberada elección frustra a maioría dos varridos de IOC estáticos.

Ademais, o fillo xerado herda o ambiente principal completo. Polo tanto, calquera NPM_TOKEN, AWS_*, GITHUB_TOKENou o socket do axente SSH presente no shell do desenvolvedor no momento da instalación viaxa á memoria do axente de longa duración.

Que inclúe o axente

O paquete src/ A árbore inclúe tres módulos cuxos nomes xa contan a historia: audioCapture.js, browserHistory.jse systemInfo.js.

A lista de dependencias en tempo de execución, resolta durante a posta en escena npm install, corróboraos.

Esta estratexia converte un incidente caótico nunha resposta controlada.

En lugar de reaccionar ás cegas, os equipos operan con priorización clara e corrección rápida.

dependenciaPara que serve neste contexto
captura-de-pantalla-escritorioCaptura de pantalla periódica
@nut-tree-fork/nut-jsAutomatización/simulación de entrada de rato e teclado
mellor-sqlite3Lecturas directas das bases de datos SQLite do historial de Chrome, Edge e Firefox
adm-zipAgrupación de artefactos recollidos antes da exfiltración
afiadoRedimensionar/comprimir capturas de pantalla e artefactos de imaxe
cliente socket.ioCanle C2 bidireccional persistente
ID-máquina-nodoPegada dixital estable por host para o seguimento de vítimas

systemInfo.js chamadas os.networkInterfaces() para obter unha toma de impresións dixitais adicional antes da primeira baliza.

Por que a captura de audio é o sinal máis destacado

A maioría dos RATs de npm que triamos en MEW detéñense no roubo secreto en tempo de instalación. Len ~/.npmrc, lea ~/.aws/credentialsraspar process.env, POST a un webhook e sae. Iso encaixa cun modelo económico de tipo "smash-and-grab". As credenciais teñen unha vida media curta e o atacante necesita monetizalas rapidamente.

node-env-resolve é diferente en forma.

A persistencia está configurada para sobrevivir ao reinicio. O axente execútase de forma desconectada e de longa duración baixo wscript.exeO kit que leva é para estar alí na máquina dun desenvolvedor, non para collelo e deixalo: un gravador de micrófono, un controlador de teclado/rato, inxestión do historial completo do navegador, captura de pantalla e un canal Socket.IO interactivo de volta a un C2 configurable.

A captura de micrófonos en particular é a liña que esta campaña cruza e que a maioría do malware npm non cruza.

Unha estación de traballo para desenvolvedores é, cada vez máis, tamén a estación de traballo onde os desenvolvedores realizan sesións de pé, chamadas con clientes, debates de deseño e pontes de garda. Un implante que grava o micrófono non está realmente detrás do token npm do desenvolvedor. Está detrás do que o desenvolvedor diante do portátil.

Ese conxunto de capacidades, xunto coa falta de ofuscación e a ausencia de calquera exfiltración chamativa en tempo de instalación, considérase un preposicionamento para o acceso específico en lugar dun roubo de credenciais oportunista.

Non estamos a afirmar unha atribución só a partir disto. Estamos a observar o perfil operativo.

ataque de typosquatting de npm - DevTab

A cadencia de iteración de oito días node-env-resolve é o detalle máis revelador desde o punto de vista operativo da liña de tempo.

Non se trata dunha entrega "dispara e esquece". O publicador mantén activamente a entrega, o que normalmente significa unha destas dúas cousas. Ou ben a está axustando para entornos de proba antes dunha implementación máis ampla, ou xa ten telemetría de instalación que volve e está a responder a ela.

Os outros cinco paquetes non experimentaron practicamente ningunha rotación despois da súa publicación inicial. Iso encaixa nun patrón de "escala unha vez, deixa co nome" para o clúster de soporte mentres que o esforzo de enxeñaría se centra no paquete que fai o traballo.

Atribución: Pequenas pistas, sen veredicto firme

público OSINT os sinais son tenues e non os estiraremos. Que se pode observar:

O identificador de Gmail tanvisoul9 parécese parcialmente a un nome de pila do sur de Asia, "Tanvi". Este é un sinal débil. Os identificadores de Gmail non son identidade e o final soul9 é xenérico. Non é seguro inferir a xeografía só a partir da parte local dun correo electrónico.

O estilo do código non é nada especial en Node.js: standard chamadas á biblioteca como os, child_process, spawne reg addNon hai ofuscación, nin rotación de cadeas, nin lóxica antidepuración. O autor sente comodidade coas primitivas do rexistro de Windows e a orquestración de procesos fillos separados, pero non parece estar a buscar técnicas comerciais máis furtivas que poderían usar.

As dependencias son totalmente preconcebidas e ben coñecidas: screenshot-desktop, nut-js, better-sqlite3e socket.io-clientNon existe ningún protocolo personalizado, ningunha pila C2 deseñada desde cero e ningún truco de persistencia novedoso máis alá dun libro de texto. Tecla de execución de HKCUEste é un integrador competente, non un autor de ferramentas.

Non atopamos cadeas de texto que non sexan en inglés, comentarios incrustados, datos de configuración rexional nin pegadas dixitais de fusos horarios de saída do compilador dentro dos artefactos publicados.

Comprobamos se o código se solapa con campañas anteriores que xa seguimos, incluíndo Shai Hulud, Owllivion, Buildkite e o recente heibai / claude-code-best Familia de clons de Anthropic-CLI. Non atopamos ningún: ningún patrón C2 compartido, ningún deseño de ficheiro compartido e ningún idioma compartido.

O que non diríamos: que se trata dun actor estatal, dun grupo coñecido ou que estea xeograficamente vinculado a ningún país específico.

O perfil operativo é consistente cun equipo pequeno e moderadamente cualificado que realiza vixilancia do posto de traballo dos desenvolvedores. É probable que a súa motivación financeira sexa o uso posterior do acceso, pero posiblemente tamén o recoñecemento como servizo para un comprador independente.

Dous puntos indirectos apoian que din: evitar mecanismos de exfiltración chamativos que queimarían o clúster rapidamente, como os bots de Telegram, oastify.com, ou canarytokens, e os nomes de paquetes deliberadamente insípidos, que favorecen as instalacións silenciosas de cola longa en lugar dun breve pico de gran volume.

Indicadores de compromiso e detección

Paquetes e editor
CampoValor
editor de npmuser0001
Correo electrónico do editortanvisoul9@gmail.com, sen verificar
Paquetescentralogger, dom-utils-lite, node-fetch-lite, axente-de-conectores, node-gyp-runtime, node-env-resolve
Malicioso confirmadonode-env-resolve@1.0.7, node-env-resolve@1.0.8
Artefactos de acollida
tipoValor
Clave de persistenciaHKCU\Software\Microsoft\Windows\Versión actual\Executar
Valor de persistenciaNome da variábel; datos do formato wscript.exe " \\ .vbs"
Instalar ganchopostinstalación: nodo postinstall.js no manifesto do paquete
Módulos de implantesrc/audioCapture.js, src/browserHistory.js, src/systemInfo.js
Directorio de probasINSTALL_DIR resolto fóra de node_modules do proxecto; localización definida por postinstall.js no momento da instalación
Rede
tipoValor
Transporte C2socket.io-client, canle bidireccional persistente
Punto final C2Fornecido ao axente a través da variable de ambiente SERVER_URL; non codificado de forma fixa nos artefactos publicados

Notas de detección

Dúas regras capturan esta familia sen precisar o extremo C2.

Primeiro, marque os scripts de postinstalación que realizan unha operación interna npm install nunha ruta fóra do directorio propio do paquete. Calquera descargador de precompilación lexítimo, como por exemplo node-gyp reconstrucións ou descargadores binarios precompilados, escribe dentro do paquete ou na plataforma-standard rutas de caché con hashes verificados. Non escribe nun ficheiro recentemente creado INSTALL_DIR noutro lugar do disco.

En segundo lugar, sinala os scripts de posinstalación que teñan problemas reg add HKCU\…\Run con wscript.exe como o lanzador. Isto esencialmente nunca é lexítimo desde un paquete npm. Márcao e pono en corentena.

Unha terceira heurística é útil para detectar o seguinte paquete irmán antes de que sexa confirmado: un novo publicador npm sen SCM verificación, un correo electrónico de Gmail, non repository campo, e varios nomes de paquetes curtos, xenéricos e que soan a infraestrutura publicados con poucos días de diferenza é, por si só, suficiente para xustificar unha revisión manual.

Informado ao rexistro de npm. Actualizaremos esta publicación cando se elimine a conta do editor.

ferramentas-sca-tools-software-ferramentas-de-análise-de-composición
Priorizar, corrixir e protexer os riscos do software
Obtén a túa conta gratuíta.
Non se precisa tarxeta de crédito.

Asegura o desenvolvemento e a entrega do teu software

con Xygeni Product Suite