Reptile: El Rootkit LKM Linux con Backdoor Integrada y Port Knocking
Análisis técnico de Reptile, rootkit LKM open-source para Linux con reverse shell cifrada, port knocking, kmatryoshka y ocultación avanzada. Usado por Kimsuky y Earth Berberoka.
Más allá de la ocultación: un rootkit con capacidad ofensiva integrada
Reptile es un rootkit LKM (Loadable Kernel Module) open-source para Linux, desarrollado por el usuario f0rb1dd3n y disponible en GitHub bajo el repositorio f0rb1dd3n/Reptile. A diferencia de rootkits minimalistas como Diamorphine, que se centran exclusivamente en la ocultación de artefactos, Reptile integra un stack ofensivo completo: backdoor con reverse shell cifrada, port knocking para activación remota, keylogger, persistencia y empaquetado del módulo con kmatryoshka.
Esta combinación lo convierte en una herramienta de post-explotación autónoma. Un atacante que despliega Reptile obtiene acceso persistente, canal de comunicación cifrado y capacidades de ocultación en un solo componente.
Por qué importa en CTI
Reptile ha sido documentado en operaciones de grupos APT reales. AhnLab ASEC identificó su uso por Kimsuky (G0094) contra organizaciones surcoreanas, y Trend Micro lo vinculó a operaciones de Earth Berberoka en el sudeste asiático. Tres factores lo hacen relevante:
- Capacidad integrada. No requiere herramientas adicionales para mantener acceso. La reverse shell con port knocking elimina la necesidad de un C2 framework separado.
- Código disponible y documentado. El repositorio incluye instrucciones de compilación, lo que facilita su modificación por threat actors con conocimientos moderados de kernel.
- Evasión de red. El magic packet opera a nivel de Netfilter (capa de kernel), invisible para herramientas de monitorización en espacio de usuario como tcpdump o Wireshark ejecutándose sobre sockets estándar.
Arquitectura: dos componentes principales
Reptile se divide en dos partes que trabajan en conjunto:
Componente kernel (reptile.ko)
El módulo del kernel implementa toda la lógica de ocultación y el listener de magic packets. Se compila contra los headers del kernel del host y se carga con insmod. Incluye:
- Hooks de syscalls (getdents/getdents64, kill, read)
- Hook de Netfilter para interceptar paquetes de red
- Filtrado de /proc/net/tcp y /proc/net/tcp6
- Mecanismo de ocultación del propio módulo
Componente userland (reptile-cmd / reptile-client)
Herramienta en espacio de usuario que permite interactuar con el módulo cargado. Proporciona comandos para:
- Ocultar/mostrar ficheros y directorios
- Ocultar/mostrar procesos por PID
- Ocultar/mostrar conexiones de red
- Obtener shell con privilegios root
Kmatryoshka: empaquetado del módulo
Kmatryoshka es el componente más distintivo de la arquitectura. Funciona como una matryoshka (muneca rusa) a nivel de kernel:
1. El módulo real (reptile.ko) se cifra con una clave definida en compilación
2. El módulo cifrado se embebe en la sección .data de un módulo loader
3. Al cargar el loader con insmod, este:
a. Descifra el payload en memoria
b. Carga el módulo real directamente desde memoria (sin tocar disco)
c. Se descarga a sí mismo, dejando solo el módulo real en memoria
El resultado: el módulo real nunca existe como fichero .ko sin cifrar en el filesystem. Las herramientas de análisis estático que escanean el disco no encuentran el rootkit en su forma ejecutable.
Syscall hooking: más hooks que Diamorphine
Reptile intercepta un conjunto más amplio de syscalls que Diamorphine. Donde Diamorphine hookea getdents64 y kill, Reptile extiende el alcance:
| Syscall/Hook | Propósito | Presente en Diamorphine |
|---|---|---|
getdents / getdents64 | Ocultar ficheros, directorios y procesos | Si |
kill | Señales mágicas para control del rootkit | Si |
tcp4_seq_show | Filtrar entradas de /proc/net/tcp | No |
tcp6_seq_show | Filtrar entradas de /proc/net/tcp6 | No |
udp4_seq_show | Filtrar entradas de /proc/net/udp | No |
udp6_seq_show | Filtrar entradas de /proc/net/udp6 | No |
Netfilter hook | Interceptar paquetes de red (magic packet) | No |
read (tty) | Keylogger via interceptación de lectura de terminales | No |
La localización de sys_call_table sigue un patrón similar al de Diamorphine (kallsyms_lookup_name o kprobes), con la diferencia de que Reptile también registra hooks en el framework de Netfilter del kernel.
Ocultación de ficheros y procesos: prefijo mágico
Reptile usa un prefijo configurable (definido en compilación, por defecto un string como reptile) para determinar qué ficheros y directorios ocultar. Cualquier entrada del filesystem cuyo nombre contenga este prefijo se filtra del resultado de getdents/getdents64:
# Comportamiento observado en sistema comprometido:
$ ls /tmp/
archivo_normal.txt datos.log
# El fichero /tmp/reptile_config existe pero no aparece en ls
$ cat /tmp/reptile_config
[contenido del fichero oculto, accesible si se conoce el nombre exacto]
Para procesos, el mecanismo es similar al de Diamorphine: el hook de getdents64 sobre /proc filtra las entradas numéricas (PIDs) marcadas como ocultas. La diferencia es que Reptile permite ocultar procesos tanto via señal mágica como via el componente userland reptile-cmd.
Ocultación de conexiones de red
Esta es una capacidad que Diamorphine no implementa. Reptile hookea las funciones del kernel que generan el contenido de /proc/net/tcp, /proc/net/tcp6, /proc/net/udp y /proc/net/udp6:
// Pseudocódigo del hook de tcp4_seq_show
static int hacked_tcp4_seq_show(struct seq_file *seq, void *v)
{
int ret = orig_tcp4_seq_show(seq, v);
// Si la conexión corresponde a un puerto oculto
// o a la IP/puerto de la reverse shell:
// Eliminar la línea del buffer de seq_file
if (should_hide_connection(v)) {
// Retroceder el puntero de escritura de seq_file
// para "borrar" la entrada que se acaba de escribir
seq->count -= bytes_written;
}
return ret;
}
El efecto práctico: herramientas como netstat, ss y cualquier programa que lea /proc/net/tcp no muestran las conexiones del rootkit. Esto oculta tanto la reverse shell activa como cualquier conexión de exfiltración.
Magic packet: activación de la reverse shell
El mecanismo más distintivo de Reptile. El módulo registra un hook de Netfilter con prioridad NF_INET_PRE_ROUTING que inspecciona todos los paquetes entrantes antes de que lleguen al stack TCP/IP normal:
Flujo del magic packet:
1. Atacante envía paquete TCP o UDP especialmente construido
2. Netfilter hook de Reptile intercepta el paquete ANTES del stack TCP/IP
3. El hook verifica:
a. ¿El payload contiene el magic value preconfigurado?
b. ¿La clave de autenticación coincide?
4. Si coincide:
a. Extrae IP destino y puerto del payload del paquete
b. Lanza un proceso en kernel space que ejecuta la reverse shell
c. La reverse shell se conecta a la IP:puerto extraída
d. El paquete original se descarta (NF_DROP) → nunca llega al userspace
5. Si no coincide: el paquete continúa normalmente (NF_ACCEPT)
La estructura del magic packet contiene:
| Campo | Tamaño | Descripción |
|---|---|---|
| Magic value | Variable | String preconfigurado en compilación |
| Clave | Variable | Clave de autenticación simétrica |
| IP destino | 4 bytes | IP a la que conectar la reverse shell |
| Puerto | 2 bytes | Puerto de la reverse shell |
| Token | Variable | Token adicional de verificación |
La reverse shell resultante se ejecuta con privilegios de root (opera desde kernel space) y la conexión se cifra. Dado que el paquete trigger nunca llega al espacio de usuario, herramientas como tcpdump, Wireshark o Suricata ejecutándose con sockets estándar no lo capturan.
Nota defensiva: Herramientas que capturan tráfico a nivel de interfaz de red (pcap en modo promiscuo con acceso directo al dispositivo) o soluciones de monitorización fuera del host (network TAP, mirror port) si pueden capturar el magic packet.
Persistencia
A diferencia de Diamorphine (que solo existe en RAM hasta el siguiente reboot), Reptile implementa persistencia activa:
- Reglas udev: Crea una regla en /etc/udev/rules.d/ que ejecuta la carga del módulo cuando se detecta un evento de dispositivo específico
- Modificación de initramfs/initrd: Variantes avanzadas inyectan el módulo en el initramfs para cargarse durante el boot, antes de que el sistema de ficheros raíz esté montado
- Scripts de inicio: Puede añadir un script en /etc/rc.local o equivalente según la distribución
La persistencia combinada con kmatryoshka hace que la reinfección sea transparente: tras un reboot, el loader descifra y carga el módulo real sin intervención del atacante.
Uso en campañas reales
Kimsuky (G0094, Corea del Norte)
AhnLab ASEC documentó en 2023 el uso de Reptile por Kimsuky contra organizaciones surcoreanas, particularmente en sectores de investigación y defensa. El grupo modificó el rootkit para:
- Cambiar los magic values y prefijos de ocultación por defecto
- Integrar la reverse shell con su infraestructura C2 existente
- Añadir recopilación de credenciales SSH del sistema comprometido
El vector de acceso inicial fue explotación de servicios web vulnerables seguida de escalada de privilegios local antes de la instalación del rootkit.
Earth Berberoka
Trend Micro identificó a Earth Berberoka (grupo vinculado a China) usando Reptile en ataques contra plataformas de juego online en el sudeste asiático. La campaña combinaba Reptile con otros componentes maliciosos para mantener acceso persistente a servidores Linux de la infraestructura de las plataformas objetivo.
Campañas de cryptomining
Múltiples campañas no atribuidas han desplegado variantes de Reptile en servidores Linux expuestos (SSH con credenciales débiles, aplicaciones web vulnerables). El patrón habitual:
1. Acceso inicial via SSH brute force o exploit de aplicación web
2. Descarga y compilación de Reptile contra headers del kernel del host
3. Instalación con kmatryoshka para dificultar análisis post-compromiso
4. Despliegue de minero XMRig con proceso oculto por el rootkit
5. Reverse shell configurada como canal de acceso alternativo
6. Conexiones del minero ocultas de /proc/net/tcp
Detección
Análisis de red
La detección más efectiva opera fuera del host comprometido:
| Método | Descripción | Efectividad |
|---|---|---|
| Network TAP / mirror port | Captura tráfico a nivel físico, incluyendo magic packets | Alta |
| IDS/IPS con reglas custom | Firmas para patrones de magic packet conocidos | Media (variantes modifican el formato) |
| Análisis de conexiones salientes | Detectar reverse shells a IPs no esperadas | Alta (si la IP C2 no está en whitelist) |
| Detección de anomalías | Paquetes UDP/TCP con payload no estándar a puertos inusuales | Media |
Análisis del host
# Comparar módulos visibles con símbolos en kallsyms
diff <(lsmod | awk '{print $1}' | sort) \
<(grep ' [a-z] ' /proc/kallsyms | awk '{print $3}' | \
sed 's/\..*//' | sort -u) | grep '>'
# Buscar discrepancias en /proc/net/tcp
# Comparar ss (userspace) con lectura directa de /proc (también hookeado)
# vs conexiones reales visibles desde otro host con nmap
# Verificar hooks de Netfilter
cat /proc/net/netfilter/nf_queue
iptables -L -v -n # Buscar hooks inesperados
# Buscar módulos con secciones .data inusualmente grandes (kmatryoshka)
# Esto requiere acceso a los .ko antes de que se carguen
find / -name "*.ko" -exec size {} \; 2>/dev/null | sort -k2 -rn
# Memory forensics con AVML (Acquire Volatile Memory for Linux)
# Extraer dump de memoria y analizar con Volatility
avml /tmp/memdump.raw
volatility -f /tmp/memdump.raw linux_check_syscall
volatility -f /tmp/memdump.raw linux_hidden_modules
Indicadores específicos de Reptile
- Strings en memoria: "reptile", "f0rb1dd3n", "kmatryoshka" (en versiones sin modificar)
- Reglas udev sospechosas en /etc/udev/rules.d/ con acciones de carga de módulo
- Modificaciones en initramfs que incluyen módulos no estándar
- Hooks registrados en NF_INET_PRE_ROUTING con funciones de callback desconocidas
Comparación con Diamorphine
| Característica | Reptile | Diamorphine |
|---|---|---|
| Líneas de código | ~3.000 | ~300 |
| Kernels soportados | 2.6.x - 5.x | 2.6.x - 6.x |
| Ocultación de procesos | Si (getdents64 + VFS hooks) | Si (getdents64 hook) |
| Ocultación de ficheros | Si (prefijo mágico) | Si (prefijo configurable) |
| Ocultación del módulo | Si (list_del + sysfs + kmatryoshka) | Si (list_del) |
| Ocultación de red | Si (tcp4/6_seq_show, udp4/6_seq_show) | No |
| Backdoor de red | Si (port knocking + reverse shell cifrada) | No |
| Escalada de privilegios | Si (señal mágica) | Si (kill -63) |
| Keylogger | Si (hook de read en tty) | No |
| Persistencia | Si (udev, initramfs, rc.local) | No (solo RAM) |
| Empaquetado | Si (kmatryoshka, cifrado) | No |
| Comunicación cifrada | Si (reverse shell cifrada) | No aplica |
| Complejidad de despliegue | Media (requiere configuración de parámetros) | Baja (compilar y cargar) |
| Superficie detectable | Mayor (más hooks, más artefactos) | Menor (minimalista) |
| Mantenimiento | Activo | Esporádico |
Reptile ofrece más funcionalidad post-explotación a costa de una superficie de ataque mayor y más artefactos detectables. Diamorphine es preferido cuando el atacante ya tiene un C2 framework y solo necesita ocultación.
Mapeo MITRE ATT&CK
| Técnica | ID | Uso en Reptile |
|---|---|---|
| Rootkit | T1014 | Categoría principal. LKM con ocultación multicapa |
| Kernel Modules and Extensions | T1547.006 | Se carga como módulo del kernel con insmod/kmatryoshka |
| Hooking | T1574.013 | Intercepta syscalls (getdents64, kill, read) y Netfilter |
| Hide Artifacts | T1564 | Oculta procesos, ficheros, conexiones de red y el propio módulo |
| Non-Standard Port | T1571 | Magic packet puede usar cualquier puerto TCP/UDP |
| Encrypted Channel | T1573 | Reverse shell con cifrado simétrico |
| Input Capture: Keylogging | T1056.001 | Hook de read() en dispositivos tty |
| Boot or Logon Initialization Scripts | T1037 | Persistencia via udev rules, initramfs, rc.local |
| Traffic Signaling: Port Knocking | T1205.001 | Magic packet activa reverse shell |
| Access Token Manipulation | T1134 | Señal mágica otorga uid 0 al proceso solicitante |
Contramedidas recomendadas
- Monitorización de red fuera del host. Desplegar TAPs o mirror ports para capturar tráfico que los hooks de Netfilter no pueden interceptar. Configurar reglas IDS para patrones de magic packets conocidos.
- Restricción de carga de módulos.
kernel.modules_disabled=1tras el boot. Module signing obligatorio conCONFIG_MODULE_SIG_FORCEpara prevenir la carga de módulos no firmados. - Integridad del initramfs. Verificar el hash del initramfs/initrd en cada boot contra un valor de referencia almacenado fuera del host (TPM, servidor de integridad).
- Memory forensics periódico. Ejecutar dumps de memoria con AVML y analizar con Volatility buscando módulos ocultos y hooks de syscall/Netfilter.
- Monitorización de udev. Alertar en SIEM cuando se crean o modifican reglas en /etc/udev/rules.d/ fuera de ventanas de mantenimiento.
- Secure Boot + Lockdown mode. Linux kernel lockdown (desde 5.4) restringe la carga de módulos no firmados y el acceso a memoria del kernel.
- eBPF para detección en tiempo real. Tracee y Falco pueden detectar la manipulación de CR0, carga de módulos que se auto-ocultan y discrepancias entre syscalls y resultados reportados.
Fuentes y referencias
- f0rb1dd3n/Reptile (repositorio original, GitHub)
- AhnLab ASEC: "Reptile Rootkit Employed by Kimsuky" (2023)
- Trend Micro: "Earth Berberoka Targets Gambling Websites" (2022)
- AhnLab ASEC: "Linux Threat Analysis: Reptile and Kmatryoshka" (2023)
- MITRE ATT&CK: T1014 Rootkit, T1547.006 Kernel Modules, T1205.001 Port Knocking
- Volatility Foundation: Linux Memory Forensics plugins
- Tracee by Aqua Security: detección de rootkits LKM via eBPF
Artículo con fines exclusivamente defensivos. El análisis de rootkits permite a equipos de seguridad mejorar sus capacidades de detección y respuesta. MalwareIntel no proporciona binarios, payloads ni instrucciones de despliegue ofensivo.
Preguntas frecuentes
Libros recomendados
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.