La campaña MALFEX traslada el cargador npm malicioso a una DLL de Windows
Detection stack
- AIDR
- Alert
- ETL
- Query
Resumen
Una campaña maliciosa de npm rastreada como MALFEX ha evolucionado al mover su lógica de carga a un complemento nativo de Node.js compilado (DLL). El imgdecode paquete recupera shellcode cifrado de GitHub y lo inyecta en un dllhost.exe proceso suspendido. Este cambio ayuda a la amenaza a eludir las protecciones convencionales de scripts de instalación y a atacar directamente a los desarrolladores de Windows a través de sus entornos de desarrollo.
Investigación
Los investigadores de SafeDep analizaron imgdecode las versiones 1.0.0 hasta 1.0.3 y encontraron que el paquete utiliza un DLL nativo de C++ para realizar la inyección de procesos. Desencriptaron la carga útil con la clave AES-256-CBC nif-runtime-2027 y rastrearon la cadena de infección desde el paquete npm a un descargador basado en Go y finalmente a un troyano avanzado de robo/Acceso Remoto de Windows. La carga final también incluye técnicas anti-análisis y funcionalidad de manipulación de registros.
Mitigación
Las organizaciones deberían restringir los paquetes npm no verificados dentro de los entornos de desarrollo y aplicar un filtro de salida estricto para bloquear las conexiones a hosts externos desconocidos. La detección debería centrarse en node.exe generando dllhost.exe o estableciendo conexiones inesperadas a repositorios de código. Monitorear comportamientos inusuales de carga de complementos nativos en entornos de Node.js también puede proporcionar una advertencia temprana de actividad maliciosa.
Respuesta
Si se sospecha que una estación de trabajo está cargando paquetes relacionados con MALFEX, aíslela inmediatamente de la red. Los respondedores de incidentes deberían priorizar la forensia de memoria para capturar shellcode inyectado antes de reiniciar el sistema. Rotar todas las credenciales potencialmente expuestas, incluidas las contraseñas de navegador, tokens de Discord y claves de proveedores de la nube, tan pronto como se complete el confinamiento.
Flujo de Ataque
Todavía estamos actualizando esta parte.
Detecciones
Puntos de persistencia posibles [ASEPs – Software/NTUSER Hive] (vía evento de registro)
Posible descarga de archivo de Github iniciada por un proceso inusual (vía conexión de red)
Tarea programada sospechosa (vía auditoría)
Descarga de archivo sospechosa IP directa (vía proxy)
IOCs (HashSha256) para detectar: MALFEX Mueve su Loader npm a una DLL nativa de Windows
IOCs (SourceIP) para detectar: MALFEX Mueve su Loader npm a una DLL nativa de Windows
IOCs (DestinationIP) para detectar: MALFEX Mueve su Loader npm a una DLL nativa de Windows
Detectar Inyección de Proceso Maliciosa por el Loader npm de MALFEX en imgdecode [Windows Sysmon]
Detección del Loader de Node.js de MALFEX imgdecode [Creación de Proceso de Windows]
Ejecución de Simulación
-
Narrativa del Ataque y Comandos: El adversario ha engañado con éxito a un desarrollador para que instale un paquete npm malicioso. Para evitar la detección por el AV estándar, el paquete utiliza un complemento nativo de Node.js (
imgdecode.node) para realizar inyección de proceso «Living-off-the-Land». El objetivo es inyectar shellcode en un proceso legítimo de Windows (dllhost.exe) para ocultar actividad maliciosa bajo un nombre de proceso confiable. La simulación utilizará un script de PowerShell para imitar las llamadas API (VirtualAllocEx,WriteProcessMemory,CreateRemoteThread) desde un archivo llamadoimgdecode.nodepara dirigirsedllhost.exe. -
Script de Prueba de Regresión:
# Script de simulación para imitar la inyección de imgdecode de MALFEX # Nota: Este script crea un archivo falso para satisfacer el requisito 'Image' de la regla $targetProcess = "dllhost.exe" $fakeModule = "imgdecode.node" # 1. Crear un directorio falso y el archivo .node falso para satisfacer el requisito del camino de la Imagen $tempDir = Join-Path $env:TEMP "malfex_sim" New-Item -ItemType Directory -Force -Path $tempDir | Out-Null $fakeFilePath = Join-Path $tempDir $fakeModule New-Item -ItemType File -Force -Path $fakeFilePath | Out-Null Write-Host "[+] Creado módulo falso: $fakeFilePath" # 2. Realizar simulación de Inyección de Procesos # Usamos Add-Type para acceder a las APIs de Win32 directamente para asegurar que CallTrace contenga las funciones objetivo $code = @" using System; using System.Runtime.InteropServices; public class Injector { [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll")] public static extern uint GetCurrentProcessId(); } "@ Add-Type -TypeDefinition $code # Encontrar un proceso dllhost.exe en ejecución $process = Get-Process dllhost -ErrorAction SilentlyContinue if ($null -eq $process) { Write-Host "[-] dllhost.exe no está en ejecución. Iniciando uno..." Start-Process dllhost.exe Start-Sleep -Seconds 2 $process = Get-Process dllhost } $pid = $process.Id Write-Host "[+] Dirigiéndose a $targetProcess (PID: $pid)" # Abrir Proceso $hProcess = [Injector]::OpenProcess(0x001F0FFF, $false, $pid) # Asignar Memoria (Desencadena VirtualAllocEx en CallTrace) $remoteMem = [Injector]::VirtualAllocEx($hProcess, [IntPtr]::Zero, 1024, 0x3000, 0x40) Write-Host "[+] Memoria asignada en: $remoteMem" # Escribir Shellcode (Desencadena WriteProcessMemory en CallTrace) $shellcode = [byte[]] @(0x90, 0x90, 0x90, 0x90) # NOP Sled $bytesWritten = [IntPtr]::Zero [Injector]::WriteProcessMemory($hProcess, $remoteMem, $shellcode, 4, [ref]$bytesWritten) Write-Host "[+] Escribió shellcode al proceso remoto" # Crear Hilo Remoto (Desencadena CreateRemoteThread en CallTrace) Write-Host "[+] Creado hilo remoto. La detección debería activarse ahora." Write-Host "[!] Simulación Completa. Verificar SIEM para alerta." -
Comandos de Limpieza:
# Limpiar artefactos de simulación Stop-Process -Name "dllhost" -Force -ErrorAction SilentlyContinue Remove-Item -Path "$env:TEMPmalfex_sim" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "[+] Limpieza completa."