La campaña MALFEX ha dado el salto de los scripts de instalación de npm a un addon nativo de Node.js: el paquete imgdecode carga una DLL de Windows que descarga shellcode cifrado desde GitHub y lo inyecta en un proceso dllhost.exe en cuanto un programa hace require del módulo. SafeDep publicó el análisis el 13 de octubre de 2026 y el 18 de octubre, a la hora de escribir esta noticia, la versión 1.0.3 seguía disponible en el registro de npm sin ningún aviso en la base de datos OSV.
Qué ha pasado
El equipo de SafeDep, un laboratorio especializado en seguridad de la cadena de suministro de software libre, publicó el 13 de octubre un informe sobre el paquete imgdecode. El paquete lo subió el 30 de septiembre de 2026 a las 22:32 UTC el usuario malfexteste8, cuya dirección de correo termina en icloud.com, y se presenta como un decodificador nativo de imágenes para pipelines de construcción. Su archivo index.js tiene nueve líneas y lo único que hace es cargar la DLL precompilada prebuilds/win32-x64/imgdecode.node. The Hacker News se hizo eco del informe el 17 de octubre.
Lo que diferencia a imgdecode de los paquetes anteriores de la campaña es que no necesita un script de instalación. SafeDep lo resume así: «The malicious code does not need a build step» (el código malicioso no necesita una fase de compilación). Desde la versión 1.0.1, la rutina maliciosa se ejecuta dentro de la función de inicialización del módulo N-API, antes de que Node.js reciba las exportaciones. Las políticas que bloquean los scripts postinstall, el recurso habitual contra paquetes maliciosos, no sirven de nada en este caso.
MALFEX es el nombre que CloudSEK (30 de septiembre) y Checkmarx Zero (5 de octubre) dieron a un operador que publica paquetes en npm desde el 6 de agosto de 2023. Checkmarx contabiliza doce paquetes, ocho de ellos maliciosos, con 40.767 descargas acumuladas según las estadísticas de npm del 1 de octubre, 3.017 de ellas en la semana anterior. Ninguno de esos informes nombraba a imgdecode. SafeDep lo conecta con la campaña porque usa el mismo repositorio de GitHub, la misma frase de cifrado que el paquete imgbundle y porque el downloader que recupera tiene el mismo hash SHA-256 que figura en la lista de indicadores de Checkmarx.
El ritmo de reposición del operador explica por qué el paquete sigue vivo. npm retiró native-runner e img-to-native el 28 de septiembre. Dos días después aparecieron sus sustitutos, imgbundle y runhelper. Este último se despublicó la misma tarde y seis horas más tarde llegó imgdecode 1.0.0, con la DLL compilada. La versión 1.0.3, publicada el 11 de octubre a las 22:09 UTC, seis días después del informe de Checkmarx, elimina la dependencia de imgbundle y funciona sin ningún otro paquete de la campaña.
Detalles técnicos
Dato | Valor |
|---|---|
Campaña | MALFEX, operador activo en npm desde el 6 de agosto de 2023 |
CVE | No aplica. Es un paquete malicioso, no una vulnerabilidad del software |
Paquete | imgdecode (registro npm), publicado por la cuenta malfexteste8 |
Versiones afectadas | 1.0.0, 1.0.1, 1.0.2 y 1.0.3 (todas maliciosas) |
Versiones corregidas | Ninguna. El paquete seguía disponible en npm el 18 de octubre de 2026 y sin aviso en OSV |
Plataforma | Windows x64 con Node.js (addon nativo N-API) |
Disparador | require('imgdecode') desde una consola interactiva, sin script de instalación |
Explotación activa | Sí. Paquete en el registro y servidor de payloads operativo el 13 de octubre de 2026 |
Paquetes relacionados | imgbundle 1.0.0 a 1.0.2 y runhelper 1.0.0 (retirados), cdn-img-fetch, img-to-native, native-runner, function-flag, function-color, tlxbnhd, tldriver y mxdriver |
SHA-256 de imgdecode.node | d7b2f6d7da81301e7f76d6812d78f4a453439141d419831522ebf7cf5bf1c714 (1.0.0), 54d995c5be97408e96db72ecc27af1dd65716f96371df085c4ce681dca623d85 (1.0.1), a53946269ffcd25c7fe1fad358c189f144dcca4d736f2b5a8ebc517a8d929dd1 (1.0.2 y 1.0.3) |
SafeDep desensambló las tres compilaciones de la DLL, todas con la misma ruta de depuración C:\Users\Administrator\Desktop\npm\imgdecode\build\Release\imgdecode.pdb. El diagrama resume la cadena de ejecución que describe el informe para la versión 1.0.3, que es el mismo binario que la 1.0.2.

La secuencia empieza con una comprobación de entorno. La DLL obtiene el handle de la salida estándar y llama a GetConsoleMode. Si la llamada falla, porque la salida va a una tubería o a un archivo, la rutina termina sin hacer nada. Es lo que ocurre en los runners de integración continua y en muchos sandboxes automáticos, así que el loader favorece la ejecución desde el terminal de un desarrollador. Las cadenas de texto van codificadas con un XOR de un byte (0x37) en bloques de 16 bytes y se decodifican en memoria con la instrucción xorps. Esta técnica de evasión es una más de las que recoge nuestro repaso de cómo el malware detecta sandboxes y máquinas virtuales.
A continuación descarga con WinINet, user agent Mozilla/5.0 y cabeceras de no caché, el archivo banner.jpg del repositorio cavecrew/proj de GitHub. La respuesta se queda en memoria y se descifra con la API CNG de Windows: AES-256 en modo CBC, con una clave que es el hash SHA-256 de la frase nif-runtime-2027 y con los primeros 16 bytes de la respuesta como vector de inicialización. Hay un detalle curioso tras el descifrado. Si el texto en claro empieza por la firma de un JPEG o de un PNG, la DLL se detiene. SafeDep deduce que el operador puede apagar el loader a distancia sirviendo un contenido cifrado que descifre a una imagen.
Para cualquier otro contenido, la DLL arranca %SystemRoot%\System32\dllhost.exe suspendido, sin ventana ni consola, reserva memoria en el proceso con VirtualAllocEx, copia los bytes descifrados con WriteProcessMemory, cambia la protección a ejecución y lectura con VirtualProtectEx y lanza un hilo remoto con CreateRemoteThread en el primer byte del buffer. El hilo principal de dllhost.exe nunca se reanuda. Si la inyección falla, una rutina alternativa ejecuta los mismos bytes dentro de node.exe con VirtualAlloc, RtlMoveMemory y CreateThread. En ambos casos el payload tiene que empezar por shellcode y no por una cabecera PE.
SafeDep no pudo recuperar banner.jpg, porque la cuenta cavecrew de GitHub ya devolvía 404 cuando empezó el análisis, así que la relación entre el loader nativo y el resto de la cadena es una inferencia. Sí recuperó del Internet Archive una captura del 6 de octubre del archivo hermano banner.png, usado por la fase en JavaScript. Es un PNG de un píxel seguido de un campo de longitud y de unos 8 MB de texto en base64 que descifra con la misma frase de paso. El resultado es un downloader en Go 1.27.1 de 6,17 MB, con hash SHA-256 2f268ca76ab27971d8b16bd4ded26e1f9cd3d4460b894af2d4bdf89f0ab7ec4b, que descarga setup.exe desde 104.234.65.75 por el puerto 700 y lo guarda como svc_update.exe. El 13 de octubre ese servidor, alojado en el AS265919 (BB Host LTDA, São Paulo), seguía sirviendo un archivo de 71,5 MB. La captura de Checkmarx muestra el código de cdn-img-fetch, el paquete de la fase en JavaScript que descargaba el mismo archivo desde el mismo repositorio y lo guardaba en una carpeta .cache.

Ese archivo de 71,5 MB es una aplicación de Node.js 18 empaquetada con pkg cuyo nombre interno es movinlike. SafeDep la analizó a partir de sus tablas de cadenas, porque el código está en bytecode de V8, y advierte de que no confirmó su ejecución. El archivo .env empaquetado contiene la dirección del mando y control (104.234.65.75, puerto 7007) y una clave de licencia con el formato MALFEX-89BEE69BB61967AF1C3B07C9, lo que apunta a un builder o a un sistema de licencias. Este build tiene un hash distinto del movinlike que analizó Checkmarx. La mayoría de los identificadores del código están en portugués (senhas, carteiras, areia, exfiltra).
Las capacidades que SafeDep infiere de esas cadenas son las de un stealer con RAT: comprobaciones de máquina virtual, de nombres de usuario de sandbox y de herramientas como x64dbg, Process Monitor o Wireshark. Robo de contraseñas y cookies de navegadores Chromium, incluido código para recuperar la clave de cifrado ligada a la aplicación de Chrome. Extracción de tokens de Discord y parcheo de discord_desktop_core/index.js para enviar a un webhook los cambios de contraseña y correo. Copia de datos de carteras de criptomonedas, de Telegram Desktop y de lanzadores de juegos (Steam, Epic Games, Riot, Battle.net, Minecraft y Ubisoft). Recogida de archivos cuyo nombre contenga seed, mnemonic, wallet, secret, token o senha, y de extensiones como .kdbx, .pem, .ppk y .env. Un canal WebSocket hacia ws://104.234.65.75:7007/agent que acepta órdenes de shell, transferencia de archivos, control de procesos, portapapeles, capturas de pantalla y control de ratón y teclado. Persistencia como %APPDATA%\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe con una clave Run y una tarea programada llamada MicrosoftEdgeUpdateService. Y una función antiforense que edita registros de los archivos EVTX de Security y Sysmon, recalcula sus sumas de comprobación y borra el historial de PowerShell. Para quien quiera comparar, nuestro análisis del troyano AsyncRAT cubre un conjunto de funciones muy parecido.
Los indicadores que publica SafeDep para esta rama de la campaña son estos:
Indicador | Tipo |
|---|---|
malfexteste8 | Cuenta de npm que publica imgdecode |
raw.githubusercontent.com/cavecrew/proj/main/banner.jpg | Descarga del shellcode cifrado (AES-256-CBC) |
raw.githubusercontent.com/cavecrew/proj/main/banner.png | Portador de la fase en JavaScript |
104.234.65.75:700/setup.exe | Descarga de la fase 3 (movinlike) |
104.234.65.75:7007, rutas /about/sendRouter y /about/discord | API de subida del stealer |
ws://104.234.65.75:7007/agent | WebSocket del RAT |
MALFEX-89BEE69BB61967AF1C3B07C9 | Clave de licencia del stealer |
nif-runtime-2027 | Frase de la clave AES (SHA-256) |
%TEMP%\svc_update.exe | Nombre de archivo de la fase 3 |
%APPDATA%\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe | Copia de persistencia |
MicrosoftEdgeUpdateService | Valor de la clave Run y tarea programada |
4f4f7d64139bde6d458a061c7fb7dd247f70f60a1ab47d87fd3634656586c106 | SHA-256 de banner.png (portador archivado) |
2f268ca76ab27971d8b16bd4ded26e1f9cd3d4460b894af2d4bdf89f0ab7ec4b | SHA-256 del downloader en Go (fase 2) |
8d50cb1ba0c2a16a673a2d08a8fb5c45bd8755c95c30ded98a84c74bfe52c9e6 | SHA-256 de setup.exe (fase 3, stealer MALFEX) |
SafeDep propone también esta regla YARA, que detecta las tres compilaciones de la DLL y que, según sus pruebas, no da falsos positivos con los addons legítimos better-sqlite3, koffi y rookie-cookies:
rule MALFEX_imgdecode_native_addon
{
meta:
description = "MALFEX imgdecode Node.js native addon that downloads, decrypts, and injects shellcode"
author = "SafeDep"
date = "2026-10-13"
reference = "pkg:npm/imgdecode"
strings:
// "nif-runtime-2027" XOR 0x37
$key_x37 = { 59 5E 51 1A 45 42 59 43 5E 5A 52 1A 05 07 05 00 }
// "https://raw.gith" XOR 0x37
$url_x37 = { 5F 43 43 47 44 0D 18 18 45 56 40 19 50 5E 43 5F }
// "WriteProcessMemo" XOR 0x37
$wpm_x37 = { 60 45 5E 43 52 67 45 58 54 52 44 44 7A 52 5A 58 }
// "CreateRemoteThre" XOR 0x37
$crt_x37 = { 74 45 52 56 43 52 65 52 5A 58 43 52 63 5F 45 52 }
$napi = "napi_register_module_v1" ascii
$pdb = "\\npm\\imgdecode\\build\\Release\\imgdecode.pdb" ascii
condition:
uint16(0) == 0x5A4D and $napi and ($pdb or 2 of ($key_x37, $url_x37, $wpm_x37, $crt_x37))
}Fuera de la regla, el informe da cuatro señales de comportamiento que, juntas, delatan este loader: una DLL en prebuilds/ dentro de un paquete sin código fuente nativo ni binding.gyp, un addon que importa WinINet o WinHTTP y bcrypt.dll sin tener código de decodificación de imágenes, node.exe como proceso padre de dllhost.exe sin el argumento /Processid:, y una conexión de node.exe a raw.githubusercontent.com seguida de otra de dllhost.exe a un host desconocido.
La rama de imgdecode es solo la más reciente. Checkmarx describe otras dos vías de entrega que no comparten infraestructura. La primera, los paquetes tlxbnhd, tldriver y mxdriver, usa scripts preinstall y postinstall para descargar de api.imghippo.com un archivo servido como PNG que en realidad es un contenedor IExpress con un intérprete AutoIt3 firmado y un script cifrado, y que termina cargando el RAT de código abierto Overlord. CloudSEK destaca que esta compilación de Overlord incluye un resolutor de mando y control que lee memos cifrados en transacciones de la blockchain de Solana, un mecanismo que Jamf había descrito como presente pero desactivado en la campaña del falso instalador de Zoom para macOS del 6 de agosto de 2026. La segunda vía es function-flag, el paquete más descargado de la campaña con 37.419 descargas, malicioso de forma continua desde el 18 de julio de 2025. Su postinstall ejecuta un ejemplo de arte ASCII con la fuente Bloody, y ese valor dispara una rutina que descarga node.exe desde cdnzona.discloud.app, lo guarda en %APPDATA% y lo ejecuta con la ventana oculta. La captura de Checkmarx enseña el truco de ocultación, con las líneas maliciosas rellenas de espacios para que queden fuera del área visible de un editor de código.

Hay una discrepancia entre informes que conviene conocer. Checkmarx y CloudSEK dan malfexteam2027 como clave de descifrado de la cadena del stealer en img-to-native, mientras que SafeDep solo consiguió descifrar los payloads de imgbundle e imgdecode con nif-runtime-2027. Los registros de OSV para imgbundle e img-to-native dan la misma frase que SafeDep. Todo apunta a que el operador cambió la clave al renovar los paquetes a finales de septiembre.
A quién afecta
Solo a equipos Windows. Las rutinas fallan en silencio en macOS y Linux porque dependen de variables como APPDATA o de API de Windows. Dentro de Windows, la víctima tipo es un desarrollador o un administrador que instala uno de estos paquetes y lo carga desde un terminal interactivo, porque la comprobación de consola de imgdecode descarta los entornos de integración continua. Checkmarx es explícito sobre la selección de objetivos: «We found no geographic or organizational targeting» (no encontramos selección geográfica ni organizativa). Cualquiera que instale el stealer se convierte en objetivo.
El alcance real es difícil de medir. SafeDep buscó imgdecode, imgbundle y el resto de nombres de la campaña en código público de GitHub, en archivos de bloqueo y en commits, y no encontró ningún proyecto público que los declare como dependencia. deps.dev tampoco muestra dependientes. La exposición se limita, por tanto, a quien instaló estos nombres directamente, incluidas las instalaciones privadas que ninguna búsqueda pública cubre. El gráfico recoge las descargas diarias de imgdecode según la API de estadísticas de npm consultada el 18 de octubre: 979 entre el 30 de septiembre y el 12 de octubre, con picos en los días de publicación de cada versión que SafeDep atribuye en parte a espejos y escáneres. El total asciende a 1.009 descargas hasta el 16 de octubre.

En España no hay aviso de INCIBE-CERT ni del CCN-CERT sobre MALFEX en el momento de escribir esta noticia. Tampoco hay víctimas confirmadas en ningún país, porque las descargas no equivalen a infecciones. Lo que sí tiene aquí mucho uso es la pieza atacada, el registro de npm, que está en cualquier equipo de desarrollo con Node.js, y el perfil de datos que roba movinlike, con las frases de recuperación de carteras de criptomonedas en primer lugar, el mismo botín que perseguía el implante hardware en dispositivos Ledger del que informamos esta semana.
Qué hacer
Lo primero es saber si alguno de los nombres de la campaña ha pasado por los proyectos de la organización. Checkmarx propone revisar el árbol de dependencias resuelto, incluidas las transitivas, y los archivos de bloqueo, porque una versión maliciosa puede seguir fijada aunque npm la haya retirado. Hemos añadido a sus comandos los tres paquetes que identificó SafeDep:
npm ls function-flag function-color cdn-img-fetch img-to-native \
native-runner tlxbnhd tldriver mxdriver imgdecode imgbundle runhelper --all
rg -n 'function-flag|function-color|cdn-img-fetch|img-to-native|native-runner|tlxbnhd|tldriver|mxdriver|imgdecode|imgbundle|runhelper' \
package-lock.json npm-shrinkwrap.json pnpm-lock.yaml yarn.lockEn los equipos Windows donde hayan estado instalados, estas comprobaciones de PowerShell buscan los artefactos documentados por Checkmarx y SafeDep. Cualquier resultado True o una tarea programada con esos nombres debe tratarse como infección probable:
Test-Path "$env:LOCALAPPDATA\ScopeSmart Technologies Inc"
Test-Path "$env:APPDATA\Microsoft\Windows\node_runtime_helper.exe"
Test-Path "$env:APPDATA\node.exe"
Test-Path "$env:APPDATA\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe"
Test-Path "$env:TEMP\svc_update.exe"
schtasks /query /tn "\Maiden" /fo LIST /v
schtasks /query /tn "MicrosoftEdgeUpdateService" /fo LIST /v
Get-CimInstance Win32_Process -Filter "Name = 'dllhost.exe'" | Where-Object { (Get-Process -Id $_.ParentProcessId -ErrorAction SilentlyContinue).Name -eq 'node' }Con los resultados en la mano, el orden de actuación que recomiendan ambos laboratorios es este:
- Trata como comprometido cualquier equipo Windows donde se haya instalado uno de estos paquetes, aunque node_modules ya no exista. Checkmarx lo dice tal cual: «Treat the host as compromised, even if node_modules has since been deleted» (trata el equipo como comprometido, aunque node_modules se haya borrado después).
- Aísla el equipo de la red y captura la memoria antes de reiniciar. El loader de imgdecode ejecuta el shellcode en memoria y un reinicio destruye la evidencia.
- Elimina la persistencia conservando copia forense: la tarea \Maiden, el directorio ScopeSmart Technologies Inc, node_runtime_helper.exe, node.exe en %APPDATA%, MicrosoftEdgeUpdate.exe en la carpeta EdgeUpdate y la tarea MicrosoftEdgeUpdateService.
- Rota desde un equipo limpio todas las credenciales que el equipo guardaba o usaba: contraseñas y cookies del navegador, tokens de Discord, sesiones de Telegram, claves cloud y SSH, y tokens de npm y de GitHub. Si el equipo guardaba frases semilla, mueve los fondos a carteras nuevas.
- Bloquea en el proxy y en el DNS las rutas concretas de los indicadores y anula la ruta a 104.234.65.75. No bloquees dominios completos como raw.githubusercontent.com, discord.com o api.imghippo.com, porque son servicios compartidos.
- Purga los once nombres de paquete de los registros privados, proxies y cachés de npm, y añádelos a las listas de bloqueo del gestor de dependencias. Bloquear un paquete no detiene a su pareja: function-color arrastra a function-flag y cdn-img-fetch siguió instalable después de que npm retirase img-to-native.
- Contrasta los registros locales de Security y Sysmon con los que haya en el SIEM o en el EDR, porque movinlike incluye código para alterarlos.
- Notifica el incidente a INCIBE-CERT si eres empresa o particular y al CCN-CERT si perteneces al sector público.
Un aviso sobre la medida más repetida en este tipo de incidentes. Instalar con la opción ignore-scripts detiene los loaders de Overlord y a function-flag, pero no a la cadena del stealer ni a imgdecode, que no tienen hook de instalación y se ejecutan al cargar el paquete. La única defensa en ese punto es no instalar el paquete, y para eso sirven el análisis de dependencias y las herramientas DevSecOps que revisan los paquetes antes de que lleguen a un equipo.
Análisis
Lo que cuenta esta noticia es una carrera entre un operador y el registro, y por ahora la va ganando el operador. Cada paquete retirado tuvo sustituto en menos de dos días, cada sustituto cambió de técnica (de ejecutable en disco a shellcode por FFI, y de ahí a una DLL nativa) y el último eslabón, imgdecode 1.0.3, lleva publicado desde el 11 de octubre, seis días después del informe de Checkmarx y dos antes del de SafeDep, y sigue ahí con un informe público desde el 13. Nosotros hemos comprobado el 18 de octubre que el registro lo sigue sirviendo como última versión y que OSV no tiene ningún aviso para él. A quien gestione un registro privado o un proxy de npm no le queda otra que bloquear por nombre sin esperar al aviso oficial.
El salto a un addon nativo cambia también el trabajo de quien revisa paquetes. Un index.js de nueve líneas no levanta sospechas y el escáner estático que busca postinstall, eval o descargas en JavaScript no ve nada, porque todo está en una DLL de la que el paquete no incluye ni el código fuente ni el binding.gyp. Eso es, precisamente, la primera señal que da SafeDep, y es una regla que puede aplicarse hoy a cualquier dependencia: un binario precompilado sin fuente que lo justifique es motivo suficiente para parar la instalación.
Hay un paralelismo con el backdoor servido por las actualizaciones de AOMEI Backupper del que informamos el 16 de octubre. En los dos casos el canal de confianza (un servidor de actualizaciones, un registro público) entrega el código sin que el usuario haga nada raro, y en los dos casos la víctima no se entera porque la ejecución se condiciona al entorno. La diferencia está en la escala, porque MALFEX acumula 40.767 descargas en tres años con un solo operador y herramientas de código abierto, y su rama más reciente no llega al millar, lo que dice mucho de lo barato que resulta hoy mantener una campaña así.
Sobre la atribución, los informes no coinciden del todo. CloudSEK habla de un operador que publica bajo cuentas en portugués, con commits en la zona horaria -0300 y un README que presenta al grupo como el equipo Malfex con Murizada como dueño. Orca Security va más allá y lo describe como un presunto actor brasileño que trabaja solo. Checkmarx se queda en que parece un único adversario y SafeDep añade que el servidor de mando y control está en São Paulo. No hay confirmación policial ni atribución oficial de ningún país, así que lo prudente es hablar de un operador lusófono y dejar la nacionalidad como hipótesis de los laboratorios.
Cronología
La cronología de Checkmarx, actualizada a 1 de octubre, dibuja tres años de actividad con un paréntesis de trece meses entre la última versión maliciosa de function-flag y la ráfaga de septiembre de 2026.

- 6 de agosto de 2023: la cuenta malfexkkj publica function-ascii, un paquete benigno que marca la actividad más antigua del operador.
- 30 de junio de 2024: function-flag aparece en npm.
- 18 de julio de 2025: function-flag pasa a ser malicioso de forma continua y se publica function-color como envoltorio que lo instala.
- 22 de septiembre de 2026: se publican tlxbnhd, tldriver y mxdriver, los loaders de Overlord. npm los retira y reciben avisos.
- 26 de septiembre: se publican cdn-img-fetch, img-to-native y native-runner. Ese día se crea el webhook de Discord que usa movinlike.
- 28 de septiembre: npm retira img-to-native y native-runner, pero cdn-img-fetch sigue instalable.
- 30 de septiembre: CloudSEK publica su informe. El operador sube imgbundle y runhelper, despublica runhelper y lanza imgdecode 1.0.0 y 1.0.1.
- 5 de octubre: Checkmarx publica su análisis de las tres vías de entrega.
- 7 y 8 de octubre: npm sustituye imgbundle, function-color, function-flag y cdn-img-fetch por paquetes de retención de seguridad.
- 11 de octubre: se publica imgdecode 1.0.3, sin dependencia de imgbundle.
- 13 de octubre: SafeDep publica el análisis del addon nativo.
- 18 de octubre: imgdecode 1.0.3 sigue en npm como última versión y sin aviso en OSV.
Preguntas frecuentes
¿Basta con borrar node_modules para limpiar un equipo?
No. Los tres laboratorios coinciden en que el equipo debe tratarse como comprometido aunque la carpeta ya no exista, porque el daño lo hace el payload descargado, que se instala fuera del proyecto (en %APPDATA%, %LOCALAPPDATA% o %TEMP%) y se mantiene con tareas programadas y claves Run. Borrar la dependencia solo cierra la puerta por la que entró.
¿Me protege instalar con npm install --ignore-scripts?
Solo en parte. Esa opción impide que se ejecuten los scripts preinstall y postinstall, así que detiene a los loaders de Overlord y a function-flag. No detiene a imgdecode ni a la cadena de cdn-img-fetch, porque su código se ejecuta cuando el programa hace require del paquete, no durante la instalación. Si el paquete está en el proyecto, acabará ejecutándose.
¿Cómo distingo un addon nativo legítimo de uno malicioso?
Un archivo .node precompilado no es malicioso por sí mismo. Lo sospechoso es la combinación de señales que da SafeDep: la DLL viene en prebuilds/ sin código fuente nativo ni binding.gyp, importa WinINet o WinHTTP y bcrypt.dll sin que el paquete haga nada de red o de cifrado, y al cargarse node.exe genera un dllhost.exe hijo sin el argumento /Processid:. La regla YARA de arriba cubre las tres compilaciones conocidas.
¿Afecta a servidores de integración continua?
Es poco probable con imgdecode, porque la DLL comprueba con GetConsoleMode que la salida estándar es una consola interactiva de Windows y en los runners la salida suele ir a una tubería. Los otros paquetes de la campaña sí se ejecutan en cualquier Windows con hooks de instalación habilitados. En Linux y macOS todas las rutinas fallan en silencio.
Quien quiera profundizar en cómo se extraen los servidores de mando y control de esta clase de stealers puede seguir el método que aplicamos en nuestro análisis dinámico de Lumma Stealer.


No hay comentarios todavía