¿Qué hace Análisis de Malware ELF en Linux?
Cuándo Usarlo
- Un servidor o contenedor Linux ha sido comprometido y se encuentran binarios ELF sospechosos
- Análisis de botnets de Linux (Mirai, Gafgyt, XorDDoS), criptomineros o ransomware
- Investigación de malware dirigido a infraestructura en la nube, contenedores Docker o pods de Kubernetes
- Ingeniería inversa de rootkits y módulos de kernel de Linux
- Análisis de malware multiplataforma compilado para Linux x86_64, ARM o MIPS
No usar para análisis de binarios PE de Windows; usar PEStudio, Ghidra o IDA para malware de Windows.
Prerrequisitos
- Ghidra o IDA con soporte para ELF de Linux para desensamblado y descompilación
- Máquina virtual de análisis Linux (se recomienda Ubuntu 22.04) con herramientas de desarrollo instaladas
- strace, ltrace y GDB para análisis dinámico y depuración
- readelf, objdump y nm de GNU binutils para inspección estática
- Radare2 para análisis rápido de binarios y análisis mediante scripts
- Docker para ejecución aislada de malware en contenedores
Flujo de Trabajo
Paso 1: Identificar Propiedades del Binario ELF
Examinar la cabecera ELF y las propiedades básicas:
# Identificación del tipo de archivo
file binario_sospechoso
# Análisis detallado de la cabecera ELF
readelf -h binario_sospechoso
# Cabeceras de sección
readelf -S binario_sospechoso
# Cabeceras de programa (segmentos)
readelf -l binario_sospechoso
# Tabla de símbolos (si no está ofuscada)
readelf -s binario_sospechoso
nm binario_sospechoso 2>/dev/null
# Información de enlace dinámico
readelf -d binario_sospechoso
ldd binario_sospechoso 2>/dev/null # ¡Solo en la arquitectura correcta!
# Calcular hashes
md5sum binario_sospechoso
sha256sum binario_sospechoso
# Verificar empaquetado/UPX
upx -t binario_sospechoso
# Análisis ELF basado en Python
from elftools.elf.elffile import ELFFile
import hashlib
with open("binario_sospechoso", "rb") as f:
data = f.read()
sha256 = hashlib.sha256(data).hexdigest()
with open("binario_sospechoso", "rb") as f:
elf = ELFFile(f)
print(f"SHA-256: {sha256}")
print(f"Clase: {elf.elfclass}-bits")
print(f"Endian: {elf.little_endian and 'Little' or 'Big'}")
print(f"Máquina: {elf.header.e_machine}")
print(f"Tipo: {elf.header.e_type}")
print(f"Punto de Entrada: 0x{elf.header.e_entry:X}")
# Verificar si está ofuscado
symtab = elf.get_section_by_name('.symtab')
print(f"Ofuscado: {'Sí' if symtab is None else 'No'}")
# Análisis de entropía de secciones
import math
from collections import Counter
for section in elf.iter_sections():
data = section.data()
if len(data) > 0:
entropy = -sum((c/len(data)) * math.log2(c/len(data))
for c in Counter(data).values() if c > 0)
if entropy > 7.0:
print(f" [!] Sección de alta entropía: {section.name} ({entropy:.2f})")
Paso 2: Extraer Cadenas e Indicadores
Buscar IOC incrustados y pistas de funcionalidad:
# Cadenas ASCII
strings binario_sospechoso > salida_cadenas.txt
# Buscar indicadores de red
grep -iE "(http|https|ftp)://" salida_cadenas.txt
grep -iE "([0-9]{1,3}\.){3}[0-9]{1,3}" salida_cadenas.txt
grep -iE "[a-zA-Z0-9.-]+\.(com|net|org|io|ru|cn)" salida_cadenas.txt
# Buscar comandos de shell
grep -iE "(bash|sh|wget|curl|chmod|/tmp/|/dev/)" salida_cadenas.txt
# Buscar indicadores de criptominería
grep -iE "(stratum|xmr|monero|pool\.|mining)" salida_cadenas.txt
# Buscar robo de credenciales SSH
grep -iE "(ssh|authorized_keys|id_rsa|shadow|passwd)" salida_cadenas.txt
# Buscar mecanismos de persistencia
grep -iE "(crontab|systemd|init\.d|rc\.local|ld\.so\.preload)" salida_cadenas.txt
# FLOSS para cadenas ofuscadas (si está disponible)
floss binario_sospechoso
Paso 3: Analizar Llamadas al Sistema y Uso de Librerías
Identificar qué llamadas al sistema y librerías usa el malware:
# Listar funciones importadas (enlazado dinámico)
readelf -r binario_sospechoso | grep -E "socket|connect|exec|fork|open|write|bind|listen"
# Rastrear llamadas al sistema durante la ejecución (solo en VM aislada)
strace -f -e trace=network,process,file -o salida_strace.txt ./binario_sospechoso
# Rastrear llamadas a librerías
ltrace -f -o salida_ltrace.txt ./binario_sospechoso
# Llamadas al sistema clave a observar:
# Red: socket, connect, bind, listen, accept, sendto, recvfrom
# Procesos: fork, execve, clone, kill, ptrace
# Archivos: open, read, write, unlink, rename, chmod
# Persistencia: inotify_add_watch (monitoreo de archivos)
Paso 4: Análisis Dinámico con GDB
Depurar el malware para observar el comportamiento en tiempo de ejecución:
# Iniciar GDB con el binario
gdb ./binario_sospechoso
# Establecer puntos de interrupción en funciones clave
(gdb) break main
(gdb) break socket
(gdb) break connect
(gdb) break execve
(gdb) break fork
# Ejecutar y analizar
(gdb) run
(gdb) info registers # Ver estado de registros
(gdb) x/20s $rdi # Examinar argumento de cadena
(gdb) bt # Traza de llamadas
(gdb) continue
# Para binarios ofuscados, interrumpir en el punto de entrada
(gdb) break *0x400580 # Punto de entrada desde readelf
(gdb) run
# Monitorear conexiones de red durante la ejecución
# En otra terminal:
ss -tlnp # Listar sockets en escucha
ss -tnp # Listar conexiones establecidas
Paso 5: Ingeniería Inversa con Ghidra
Realizar análisis profundo de código en el binario ELF:
Análisis Ghidra para ELF de Linux:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Importar: File -> Import -> Seleccionar binario ELF
- Ghidra detecta automáticamente el formato ELF y la arquitectura
- Aceptar opciones de análisis predeterminadas
2. Objetivos de análisis clave:
- Función main() (o punto de entrada si está ofuscado)
- Funciones de creación y conexión de sockets
- Lógica de despacho de comandos (switch/case en datos recibidos)
- Rutinas de cifrado/codificación
- Código de instalación de persistencia
- Funciones de autopropagación/escaneo
3. Para botnets tipo Mirai, buscar:
- Lista de credenciales para fuerza bruta (telnet/SSH)
- Selección de módulos de ataque (inundación UDP, SYN, ACK)
- Módulo de escaneo (escaneo de puertos para dispositivos vulnerables)
- Módulo eliminador (eliminar botnets competidoras)
4. Para criptomineros, buscar:
- Conexión a pool de minería (protocolo stratum)
- Cadenas de dirección de billetera
- Funciones de utilización de CPU/GPU
- Técnicas de ocultación de procesos
Paso 6: Analizar Persistencia Específica de Linux
Verificar mecanismos de persistencia:
# Verificar rootkit LD_PRELOAD
strings binario_sospechoso | grep "ld.so.preload"
# El malware escribiendo en /etc/ld.so.preload puede interceptar todas las llamadas a librerías dinámicas
# Verificar persistencia en crontab
strings binario_sospechoso | grep -i "cron"
# Verificar creación de servicio systemd
strings binario_sospechoso | grep -iE "systemd|\.service|systemctl"
# Verificar creación de script init
strings binario_sospechoso | grep -iE "init\.d|rc\.local|update-rc"
# Verificar inyección de claves SSH
strings binario_sospechoso | grep -i "authorized_keys"
# Verificar carga de módulo de kernel (rootkit)
strings binario_sospechoso | grep -iE "insmod|modprobe|init_module"
# Verificar ocultación de procesos
strings binario_sospechoso | grep -iE "proc|readdir|getdents"
Conceptos Clave
| Término | Definición |
|---|---|
| ELF (Executable and Linkable Format) | Formato binario estándar para ejecutables de Linux, librerías compartidas y volcados de núcleo que contiene cabeceras, secciones y segmentos |
| Binario Ofuscado | Binario ELF con símbolos de depuración eliminados, lo que dificulta la ingeniería inversa al perderse los nombres de funciones |
| LD_PRELOAD | Variable de entorno de Linux que especifica librerías compartidas a cargar antes que todas las demás; es abusada por rootkits para interceptar llamadas a librerías del sistema |
| strace | Rastreador de llamadas al sistema de Linux que registra todas las llamadas al sistema y señales realizadas por un proceso, revelando operaciones de archivos, red y procesos |
| GOT/PLT | Tabla de Desplazamiento Global y Tabla de Enlace de Procedimientos; estructuras ELF para enlace dinámico que pueden ser secuestradas para interceptación de funciones |
| Enlazado Estático | Binario compilado con todo el código de librerías incluido; común en malware IoT para ejecutarse en sistemas sin las librerías compartidas correspondientes |
| Mirai | Botnet prolífica de Linux que ataca dispositivos IoT mediante fuerza bruta telnet; su código fuente se filtró, dando lugar a muchas variantes |
Herramientas y Sistemas
- Ghidra: Herramienta de ingeniería inversa de la NSA con soporte completo para ELF en x86, x86_64, ARM, MIPS y otras arquitecturas Linux
- Radare2: Framework de ingeniería inversa de código abierto con interfaz de línea de comandos para análisis rápido de binarios y scripting
- strace: Herramienta de rastreo de llamadas al sistema de Linux para observar el comportamiento del binario, incluyendo operaciones de archivos, red y procesos
- GDB: Depurador GNU para establecer puntos de interrupción, examinar memoria y recorrer la ejecución de binarios Linux
- pyelftools: Librería Python para analizar archivos ELF de forma programática para procesos de análisis automatizados
Escenarios Comunes
Escenario: Análisis de un Criptominero Encontrado en un Servidor Linux Comprometido
Contexto: Un servidor en la nube muestra un uso de CPU del 100%. La investigación revela un binario desconocido ejecutándose desde /tmp con un nombre sospechoso. El binario necesita análisis para confirmar que es un criptominero e identificar la billetera y el pool del atacante.
Enfoque:
- Copiar el binario a una VM de análisis y calcular el hash SHA-256
- Ejecutar
fileyreadelfpara identificar la arquitectura y el tipo de enlace - Extraer cadenas y buscar direcciones de pool de minería (stratum+tcp://) y direcciones de billetera
- Ejecutar con strace en un entorno aislado para observar conexiones de red (conexión al pool de minería)
- Importar en Ghidra para identificar el algoritmo de minería y la extracción de configuración
- Verificar mecanismos de persistencia (crontab, servicio systemd, claves SSH)
- Documentar todos los IOC, incluyendo dirección del pool, billetera, C2 para actualizaciones y artefactos de persistencia
Errores Comunes:
- Ejecutar
ldden malware fuera de un entorno aislado (ldd puede ejecutar código en el binario) - No verificar la arquitectura ARM/MIPS antes de intentar ejecución x86_64
- Omitir scripts complementarios (.sh) que pueden manejar persistencia y limpieza
- Ignorar el vector de acceso inicial (cómo se desplegó el minero: fuerza bruta SSH, exploit web, escape de contenedor)
Formato de Salida
INFORME DE ANÁLISIS DE MALWARE ELF EN LINUX
=============================================
Archivo: /tmp/.X11-unix/.rsync
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
Tipo: ELF 64-bit LSB executable, x86-64
Enlace: Estático (todas las librerías incrustadas)
Ofuscado: Sí
Tamaño: 2,847,232 bytes
Empaquetador: UPX 3.96 (desempaquetado para análisis)
CLASIFICACIÓN
Familia: XMRig Cryptominer (modificado)
Variante: Compilación personalizada con mecanismo de actualización C2
FUNCIONALIDAD
[*] Minería XMR (Monero) mediante algoritmo RandomX
[*] Conexión a pool Stratum para envío de trabajo
[*] Comprobación con C2 para obtener actualizaciones de configuración
[*] Ocultación del nombre del proceso (argv[0] = "[kworker/0:0]")
[*] Eliminación de procesos competidores (mata otros mineros)
[*] Inyección de claves SSH para reingreso
INDICADORES DE RED
Pool de Minería: stratum+tcp://pool.minexmr[.]com:4444
Servidor C2: hxxp://update.malicious[.]com/config
Billetera: 49jZ5Q3b...Dirección_Billetera_Monero...
PERSISTENCIA
[1] Entrada en crontab: */5 * * * * /tmp/.X11-unix/.rsync
[2] Clave SSH añadida a /root/.ssh/authorized_keys
[3] Servicio systemd: /etc/systemd/system/rsync-daemon.service
[4] /etc/ld.so.preload modificado para ocultar procesos
OCULTACIÓN DE PROCESOS
LD_PRELOAD: /usr/lib/.libsystem.so
Hook: readdir() para ocultar /tmp/.X11-unix/.rsync de ls
Hook: fopen() para ocultar de la lectura de /proc/*/maps