Avanzadomemory forensicsmalfindcode injectionVADVolatilityavanzado

Malfind y Deteccion de Code Injection en Memoria con Volatility 3

Uso avanzado del plugin malfind de Volatility 3 para detectar inyeccion de codigo en memoria. Analisis de VADs (Virtual Address Descriptors), permisos PAGE_EXECUTE_READWRITE, shellcode, reflective DLL injection y tecnicas para distinguir verdaderos positivos de falsos positivos.

MalwareIntel Research··9 min lectura
Serie: Memory Forensics — Parte 7

La frontera entre codigo legitimo y codigo inyectado

La inyeccion de codigo es una de las tecnicas mas usadas por malware moderno. El principio es simple: en lugar de ejecutar un binario malicioso como proceso independiente (que seria visible y detectable), el atacante inserta su codigo dentro de un proceso legitimo. Desde fuera, el sistema parece ejecutar solo procesos normales. Por dentro, uno de esos procesos contiene y ejecuta el payload del atacante.

Volatility 3 ofrece el plugin malfind como primera linea de deteccion de estas tecnicas. Este articulo explica como funciona malfind internamente, como interpretar sus resultados, como reducir falsos positivos y como analizar el codigo inyectado que encuentres.

Virtual Address Descriptors (VADs)

Para entender malfind, necesitas entender los VADs. El arbol VAD (Virtual Address Descriptor tree) es una estructura del kernel de Windows que describe todas las regiones de memoria asignadas a un proceso.

Cada nodo VAD contiene:

  • Direccion de inicio y fin de la region.
  • Proteccion (permisos): PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, etc.
  • Tipo de respaldo: si la region esta respaldada por un fichero en disco (image-backed) o es memoria anonima (private).
  • Nombre del fichero si esta respaldada por un fichero (la DLL o EXE).
  • Estado de compromiso (committed, reserved, free).

Para ver el arbol VAD de un proceso:

vol -f memory.raw windows.vadinfo --pid 4321

Salida parcial:

PID    Process      Offset           Start            End              Tag    Protection                     PrivateMemory  FileObject
4321   svchost.exe  0xfa8001234000   0x7ff600000000   0x7ff60001bfff   VadS   PAGE_EXECUTE_READ              0              \Windows\System32\svchost.exe
4321   svchost.exe  0xfa8001234100   0x7ffb12340000   0x7ffb12537fff   VadS   PAGE_EXECUTE_READ              0              \Windows\System32\ntdll.dll
4321   svchost.exe  0xfa8001234200   0x0000deadb000   0x0000deacffff   VadS   PAGE_EXECUTE_READWRITE         1              -

La ultima entrada es sospechosa: memoria privada (PrivateMemory=1), con permisos PAGE_EXECUTE_READWRITE, sin fichero asociado. Esto es exactamente lo que malfind busca.

Plugin malfind: deteccion automatica

vol -f memory.raw windows.malfind

Para un proceso especifico:

vol -f memory.raw windows.malfind --pid 4321

Salida tipica cuando encuentra algo sospechoso:

PID    Process      Start            End              Tag    Protection                     Hexdump                          Disasm
4321   svchost.exe  0x0000deadb000   0x0000deacffff   VadS   PAGE_EXECUTE_READWRITE
4d 5a 90 00 03 00 00 00   MZ......
04 00 00 00 ff ff 00 00   ........
b8 00 00 00 00 00 00 00   ........
40 00 00 00 00 00 00 00   @.......

malfind reporta:

  • El PID y nombre del proceso.
  • El rango de direcciones de la region sospechosa.
  • Los permisos de la region.
  • Un hexdump de los primeros bytes.
  • Un desensamblado (si Capstone esta instalado).

Interpretacion de resultados

Cabecera MZ (PE header)

Si los primeros bytes son 4d 5a (MZ en ASCII), la region contiene un ejecutable PE (Portable Executable). Esto es un indicador fuerte de una DLL o EXE mapeado manualmente en memoria sin usar el loader estandar de Windows. Escenarios:

  • Reflective DLL injection: la DLL completa esta en memoria anonima.
  • Process hollowing: el ejecutable original fue reemplazado por otro.
  • Manual mapping: un packer o loader mapeo un PE manualmente.

Shellcode

Si los primeros bytes no son una cabecera PE sino instrucciones de ensamblador, probablemente es shellcode. Patrones comunes de shellcode x64:

fc 48 83 e4 f0    ; cld; and rsp, -10h
48 31 c9          ; xor rcx, rcx
65 48 8b 04 25    ; mov rax, gs:[...]

El shellcode tipico de frameworks como Cobalt Strike, Metasploit o Havoc C2 comienza con un prologo que configura el stack y busca las direcciones de las funciones del sistema.

Codigo desempaquetado

Algunos malware se empaquetan (con UPX, Themida, VMProtect) y se desempaquetan en memoria en tiempo de ejecucion. La region PAGE_EXECUTE_READWRITE contiene el codigo original descomprimido, que es la version "real" del malware. Esto es valioso forense porque el fichero en disco esta ofuscado, pero la version en memoria esta limpia.

Reduccion de falsos positivos

malfind genera muchos falsos positivos en sistemas modernos. Es necesario filtrar:

.NET Runtime y JIT

El Common Language Runtime (CLR) de .NET usa compilacion Just-In-Time. Los metodos .NET se compilan a codigo nativo en memoria en regiones PAGE_EXECUTE_READWRITE. Si el proceso es una aplicacion .NET (tiene clr.dll o mscorlib.dll en su dlllist), las regiones RWX son probablemente JIT y no inyeccion.

Para verificar:

vol -f memory.raw windows.dlllist --pid 4321 | grep -i "clr\|mscor\|coreclr"

Si aparece clr.dll o coreclr.dll, el proceso es .NET y las regiones RWX pueden ser legitimas.

Java y JVM

Similar a .NET, la JVM compila bytecode a codigo nativo en runtime. Procesos java.exe o javaw.exe con regiones RWX son normales.

Chrome, Firefox y Edge usan motores JavaScript con JIT (V8, SpiderMonkey, Chakra) que generan codigo nativo en regiones RWX. Los procesos de renderizado del navegador (chrome.exe child processes) tendran regiones RWX normales.

Drivers de impresora y otros

Algunos drivers de terceros asignan memoria RWX en procesos del sistema. Si una region RWX aparece en un svchost.exe que aloja el servicio Spooler, puede ser el driver de impresora.

Filtrado practico

Estrategia para reducir ruido:

  1. Ignorar procesos conocidos por usar JIT (.NET, Java, browsers) a menos que tengan otros indicadores sospechosos.
  2. Buscar cabeceras MZ en las regiones RWX. Una cabecera MZ en memoria privada es casi siempre maliciosa.
  3. Verificar el tamano de la region. Regiones muy pequenas (menos de 4 KB) pueden ser datos o metadatos, no codigo. Regiones de 50 KB o mas con cabecera MZ son muy sospechosas.
  4. Cruzar con netscan. Si el proceso con regiones RWX tambien tiene conexiones externas sospechosas, sube la prioridad.

Volcado de regiones sospechosas

Cuando malfind encuentra algo interesante, extrae la region para analisis:

vol -f memory.raw windows.malfind --pid 4321 --dump

Esto genera ficheros con la region de memoria completa. Puedes analizarlos con:

YARA: ejecutar reglas YARA contra el dump para identificar familias conocidas:

yara rules.yar dumped_region.dmp

strings: buscar cadenas indicativas (URLs, IPs, claves de registro, nombres de fichero):

strings -n 8 dumped_region.dmp

Desensamblado: cargar en Ghidra o IDA Pro para analisis de codigo.

Hash: calcular el hash y buscarlo en MalwareBazaar o VirusTotal.

Plugin vadyarascan: YARA sobre VADs

Para buscar patrones YARA especificos en regiones de memoria:

vol -f memory.raw yarascan.YaraScan --yara-file /path/to/rules.yar

Para limitar la busqueda a un proceso:

vol -f memory.raw yarascan.YaraScan --yara-file rules.yar --pid 4321

Esto es mas eficiente que ejecutar YARA contra el dump completo porque Volatility entiende la estructura de la memoria y puede aplicar las reglas solo a las regiones relevantes.

Tecnicas de inyeccion y como las detecta malfind

Classic DLL Injection (via LoadLibrary)

malfind generalmente NO detecta esta tecnica porque la DLL se carga con LoadLibrary, se registra en el PEB y tiene proteccion PAGE_EXECUTE_READ (no RWX). Se detecta mejor con dlllist/ldrmodules revisando rutas de DLLs sospechosas.

Reflective DLL Injection

malfind DETECTA esta tecnica porque la DLL se mapea manualmente en memoria privada con permisos RWX. Aparece como una region con cabecera MZ que no esta en el PEB.

Process Hollowing

malfind puede detectar el contenido reemplazado. Si el ejecutable original fue vaciado y reemplazado por otro, la region del ejecutable principal tendra un PE diferente al que esta en disco. El plugin hollowfind (community) es mas especifico para este caso.

Shellcode injection (CreateRemoteThread, APC injection, etc.)

malfind DETECTA estas tecnicas porque el shellcode reside en memoria privada con permisos RWX. Aparece como una region sin cabecera PE pero con instrucciones ejecutables.

Thread hijacking

El atacante modifica el puntero de instruccion (RIP) de un thread existente para que apunte a su shellcode. malfind detecta la region de shellcode, pero la relacion con el thread hijacked requiere analisis adicional del estado de los threads.

Early Bird injection

Similar a process hollowing pero inyecta en la fase de inicializacion del proceso (antes de que el entry point original se ejecute). malfind detecta la region inyectada.

Analisis avanzado de VADs

Para un analisis mas profundo de las regiones de memoria:

vol -f memory.raw windows.vadinfo --pid 4321

Busca patrones como:

Multiples regiones RWX consecutivas. Un solo region RWX puede ser JIT. Multiples regiones RWX del mismo tamano pueden indicar un packer que desempaqueta en fases.

Region RWX grande (varios MB). Los JIT suelen usar regiones mas pequenas. Una region RWX de 5 MB o mas que contiene un PE completo es muy probablemente maliciosa.

Transiciones de permisos. Algunos malware asignan memoria como RW (sin execute), escriben su codigo, y luego cambian los permisos a RX con VirtualProtect. Esto no aparece como RWX en el momento de la captura, pero malfind puede no detectarlo si ya cambio los permisos.

Caso practico: Cobalt Strike beacon en memoria

Un escenario comun es encontrar un beacon de Cobalt Strike inyectado en un proceso legitimo.

vol -f memory.raw windows.malfind --pid 1024

Resultado:

PID    Process       Start            Protection                     Hexdump
1024   svchost.exe   0x00000180b000   PAGE_EXECUTE_READWRITE
4d 5a 90 00 03 00 00 00   MZ......

Una cabecera MZ en svchost.exe en memoria privada. Extraemos y ejecutamos YARA:

vol -f memory.raw windows.malfind --pid 1024 --dump
yara cobalt_strike.yar dumped_files/

Si la regla YARA coincide con el patron de Cobalt Strike beacon (configuracion en formato de malleable C2, magic bytes especificos), tenemos identificacion positiva.

Strings del dump pueden revelar la configuracion del beacon:

.http-get.uri "/updates/check"
.http-post.uri "/submit/data"
.spawnto_x64 "%windir%\\sysnative\\dllhost.exe"
.watermark 123456789

Estos valores permiten identificar el operador (watermark), la infraestructura C2 (URIs) y las tecnicas de evasion configuradas.

Complemento: plugin malfind vs hollowfind

Capacidadmalfindhollowfind
RWX sin fichero respaldoSiNo (enfocado en otra cosa)
PE en memoria privadaSiSi
Discrepancia PE memoria vs discoNoSi
Shellcode sin cabecera PESiNo
DisponibilidadCore Volatility 3Community plugins

Para una deteccion completa, ejecuta ambos. malfind cubre inyeccion general y hollowfind cubre especificamente process hollowing.

Proximo paso

El siguiente articulo cubre el analisis de artefactos del registro de Windows en memoria: hivelist, printkey, y como extraer hashes de contrasenas, historial USB y claves de persistencia desde el volcado de memoria.

Preguntas frecuentes

Artículos relacionados

Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.