AvanzadorootkitsWinDbgkernel-debugginglabanalysisWindows

Laboratorio WinDbg para Analisis de Rootkits: Kernel Debugging Paso a Paso

Guia completa para montar un laboratorio de kernel debugging con WinDbg orientado al analisis de rootkits. Configuracion, comandos esenciales y ejercicios practicos de deteccion.

MalwareIntel Research··10 min lectura
Serie: Rootkits y Bootkits — Parte 22

Por que WinDbg para rootkits

Las herramientas de analisis en user-mode (Process Explorer, Process Monitor) ven lo que el kernel les permite ver. Si un rootkit manipula las estructuras del kernel, esas herramientas muestran informacion falsa. WinDbg conectado en modo kernel debugging opera a nivel del depurador del procesador: lee memoria fisica directamente, no depende de las APIs que el rootkit puede haber comprometido.

Volatility trabaja sobre volcados de memoria (analisis post-mortem). WinDbg trabaja en vivo, con la posibilidad de poner breakpoints, inspeccionar registros del procesador, y observar el rootkit mientras se carga y ejecuta. Son herramientas complementarias, no sustitutas.

Arquitectura del laboratorio

El setup requiere dos sistemas: un host que ejecuta WinDbg y un target donde corre el Windows a depurar. La comunicacion entre ambos puede ser por named pipe (si el target es una VM), red (TCP/IP), serial o USB 3.0.

Opcion recomendada: Host + VM via named pipe

La configuracion mas accesible para un laboratorio. El host ejecuta el hipervisor (Hyper-V, VMware, VirtualBox) y WinDbg. La VM target ejecuta Windows con kernel debugging habilitado.

Host (depurador):

  • Windows 10/11 con WinDbg instalado
  • Hipervisor con soporte de named pipes o serial virtual
  • Minimo 16 GB RAM (8 GB para el host, 4-8 GB para la VM)

Target (VM depurada):

  • Windows 10/11 (preferible la misma version major que el host)
  • Kernel debugging habilitado via bcdedit
  • Test signing habilitado (para cargar drivers no firmados en el lab)

Opcion alternativa: debugging por red

Disponible desde Windows 8. Mas rapido que serial/named pipe. Util cuando el target es una maquina fisica o una VM en otro equipo.

# En el TARGET (cmd como administrador):
bcdedit /debug on
bcdedit /dbgsettings net hostip:192.168.1.100 port:50000

# El comando devuelve una key que necesitas en el host:
# Key=1a2b3c4d5e6f.7a8b9c0d1e2f.3a4b5c6d7e8f.9a0b1c2d3e4f

Instalacion de WinDbg

WinDbg Preview (recomendado)

Instalar desde Microsoft Store buscando "WinDbg" o descargar el paquete MSIX desde la documentacion de Microsoft. Incluye Time Travel Debugging, mejor interfaz y scripting moderno.

WinDbg clasico

Viene incluido en el Windows SDK (Windows Software Development Kit). Durante la instalacion del SDK, seleccionar solo "Debugging Tools for Windows". El ejecutable queda en C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe.

Ambos comparten el motor dbgeng.dll. Los comandos y extensiones son identicos. La diferencia es la interfaz.

Habilitar kernel debugging en el target

Ejecutar en el target como administrador:

bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200
bcdedit /set testsigning on

El parametro testsigning on permite cargar drivers sin firma digital valida. Esto es necesario en el laboratorio para cargar drivers de prueba que simulen comportamiento de rootkit. En produccion, test signing debe estar desactivado.

Para debugging por named pipe en VMware, configurar un puerto serial virtual en la VM apuntando a \\.\pipe\com_debug. En VirtualBox, anadir un puerto serial en modo "Host Pipe" con path \\.\pipe\windbg_pipe.

Reiniciar la VM. Al arrancar, el kernel espera conexion del depurador.

Conectar WinDbg al target

En WinDbg del host: File > Attach to Kernel (o Ctrl+K).

Para named pipe:

com:pipe,port=\\.\pipe\com_debug,resets=0,reconnect

Para red:

net:port=50000,key=1a2b3c4d5e6f.7a8b9c0d1e2f.3a4b5c6d7e8f.9a0b1c2d3e4f

Cuando la conexion se establece, WinDbg muestra el prompt kd>. El target esta detenido. Pulsar g (go) para que continue la ejecucion. Pulsar Ctrl+Break para detener el target en cualquier momento.

Configuracion de simbolos

Los simbolos son esenciales. Sin ellos, WinDbg muestra direcciones hexadecimales en vez de nombres de funciones y estructuras.

# En WinDbg, configurar el path de simbolos:
.sympath srv*C:\Symbols*https://msdl.microsoft.com/download/symbols

# Forzar recarga de simbolos:
.reload /f

# Verificar que ntoskrnl tiene simbolos:
lm m nt
# Debe mostrar: nt (pdb symbols) c:\symbols\ntkrnlmp.pdb\...

Crear la carpeta C:\Symbols antes de la primera sesion. WinDbg descarga y cachea los PDBs automaticamente. La primera sesion tarda mas porque descarga varios cientos de MB de simbolos.

Comandos esenciales para analisis de rootkits

Listar todos los procesos

!process 0 0

Recorre la lista enlazada de EPROCESS del kernel (la misma que un rootkit DKOM desenlaza). Muestra PID, nombre de imagen, direccion del EPROCESS, y estado de cada proceso.

Examinar la estructura EPROCESS

dt nt!_EPROCESS

Muestra todos los campos de la estructura EPROCESS. Los mas relevantes para rootkits:

dt nt!_EPROCESS <direccion>
# Campos clave:
#   +0x000 Pcb               : _KPROCESS
#   +0x2e8 ActiveProcessLinks : _LIST_ENTRY    <- DKOM desenlaza esto
#   +0x338 UniqueProcessId    : Ptr64 Void      <- PID
#   +0x440 ImageFileName      : [15] UChar       <- nombre del proceso
#   +0x448 ThreadListHead     : _LIST_ENTRY
#   +0x570 Token              : _EX_FAST_REF     <- token de seguridad

Los offsets varian entre versiones de Windows. Usar siempre dt para obtener los correctos en el target.

Inspeccionar objetos del kernel

!object \ObjectTypes

Lista todos los tipos de objetos del kernel (Process, Thread, File, Driver, Device, etc.). Util para verificar que no hay tipos de objetos manipulados.

Examinar la SSDT

# Mostrar la tabla de servicios:
dd nt!KiServiceTable L 0x200

# O con el comando de extension:
!ssdt

Cada entrada de la SSDT contiene un offset relativo a la base de la tabla. Si alguna entrada apunta fuera del rango de ntoskrnl.exe, es un hook.

Examinar la IDT

!idt

Muestra la Interrupt Descriptor Table. Verificar que las entradas criticas (int 0x2E en x86, MSR LSTAR en x64) apuntan a direcciones dentro de ntoskrnl.

Inspeccionar un driver

!drvobj \Driver\NombreDriver 2

Muestra la estructura DRIVER_OBJECT incluyendo la tabla de dispatch (MajorFunction). Si las funciones de dispatch apuntan a un modulo diferente del driver, algo las ha hookeado.

Modulos cargados

lm

Lista todos los modulos cargados en el kernel. Cada modulo muestra direccion base, tamano y nombre. Un rootkit cargado como driver aparece aqui (a menos que oculte su propia entrada).

# Buscar un modulo especifico:
lm m rootkit*

# Modulos sin simbolos (sospechosos):
lm f

Ejercicio 1: detectar procesos ocultos por DKOM

Un rootkit DKOM desenlaza el EPROCESS de la lista ActiveProcessLinks. !process 0 0 recorre esa lista y no ve el proceso oculto. Pero el EPROCESS sigue en memoria.

Paso 1: Listar procesos con la lista enlazada:

!process 0 0

Paso 2: Buscar EPROCESS por pool tags en toda la memoria:

!poolfind Proc 0

Este comando busca el pool tag "Proc" (asignado por ExAllocatePoolWithTag al crear procesos) en toda la memoria no paginada. Encuentra EPROCESS que ya no estan en la lista enlazada.

Paso 3: Comparar ambas listas. Los EPROCESS encontrados por pool scanning pero ausentes en !process 0 0 son procesos ocultos por DKOM.

Paso 4: Inspeccionar el EPROCESS oculto:

dt nt!_EPROCESS <direccion_encontrada>
# Verificar ImageFileName, UniqueProcessId, Token

Esta es exactamente la misma tecnica que usa Volatility con pslist vs psscan, pero ejecutada en vivo.

Ejercicio 2: detectar SSDT hooks

Paso 1: Obtener el rango de direcciones de ntoskrnl:

lm m nt
# Ejemplo: fffff800`04000000  fffff800`04800000  nt

Paso 2: Volcar la SSDT:

dd nt!KiServiceTable L 0x200

Paso 3: Para cada entrada, calcular la direccion absoluta. En x64, las entradas de la SSDT son offsets relativos de 32 bits (con shift de 4 bits):

# Direccion real = KiServiceTable + (entrada >> 4)
? nt!KiServiceTable + (poi(nt!KiServiceTable + <indice> * 4) >> 4)

Paso 4: Verificar que la direccion resultante cae dentro del rango de ntoskrnl. Si apunta a otro modulo, es un hook. Identificar el modulo con:

lm a <direccion_sospechosa>

Ejercicio 3: examinar callbacks del kernel

Los rootkits modernos (post-PatchGuard) prefieren registrar callbacks legitimos del kernel para interceptar operaciones sin modificar tablas protegidas.

Callbacks de creacion de procesos:

# Localizar el array de callbacks:
dx @$cursession.Processes.Select(p => p.Name)

# Inspeccionar PsSetCreateProcessNotifyRoutine callbacks:
dt nt!_EX_CALLBACK_ROUTINE_BLOCK poi(nt!PspCreateProcessNotifyRoutine)
dt nt!_EX_CALLBACK_ROUTINE_BLOCK poi(nt!PspCreateProcessNotifyRoutine+8)
# Repetir para cada entrada del array (hasta 64 slots)

Callbacks de registro (CmRegisterCallback):

!reg callbacks

Callbacks de objetos (ObRegisterCallbacks):

# Listar las callback registrations:
dt nt!_CALLBACK_ENTRY_ITEM poi(nt!ObpCallbackListHead)

Para cada callback, verificar que la funcion registrada pertenece a un modulo conocido y firmado. Un callback que apunta a un driver desconocido o sin simbolos merece investigacion.

Ejercicio 4: verificar integridad del kernel

Comparar las instrucciones en memoria del kernel con las del archivo ntoskrnl.exe en disco.

Paso 1: Localizar una funcion sospechosa:

u nt!NtCreateFile L 20

Paso 2: Comparar con el archivo en disco. Primero, cargar la imagen desde disco:

.reload /i /f ntoskrnl.exe
# Comparar la imagen en memoria con la de disco byte a byte en la funcion:
!chkimg nt -d

El comando !chkimg compara cada byte del modulo en memoria contra el archivo en disco. Reporta las diferencias con su offset. Cualquier discrepancia en la seccion de codigo (.text) es un patch no autorizado (inline hook o detour).

Driver Verifier para analisis de carga de drivers

Driver Verifier es una herramienta de Windows que instrumenta drivers con verificaciones adicionales. Para analisis de rootkits, es util para interceptar la carga de un driver sospechoso.

# En el target (cmd como administrador):
verifier /standard /driver nombre_del_driver.sys

# Para monitorear TODOS los drivers no firmados:
verifier /standard /all

Con Driver Verifier activo y kernel debugging conectado, WinDbg puede interceptar la carga del driver con un breakpoint en nt!IopLoadDriver:

bp nt!IopLoadDriver
g
# Cuando el breakpoint se activa, inspeccionar los parametros:
!drvobj \Driver\NombreDriver 7

Esto permite observar el driver antes de que ejecute su rutina DriverEntry, donde tipicamente instala hooks y registra callbacks.

Scripts y automatizacion en WinDbg

WinDbg soporta scripts para automatizar tareas repetitivas.

Breakpoint condicional que logea sin detener:

bp nt!NtCreateFile ".printf \"NtCreateFile called by PID=%d\\n\", @$tpid; g"

Script para listar todos los drivers y sus dispatch tables:

.foreach (drv {lm 1m}) {
    .if ($sicmp("${drv}", "nt") != 0) {
        .printf "--- %s ---\\n", "${drv}";
        !drvobj \Driver\${drv} 2
    }
}

Verificacion rapida de integridad de multiples modulos:

!chkimg nt -d
!chkimg win32k -d
!chkimg ndis -d
!chkimg fltmgr -d

Mapeo MITRE ATT&CK (perspectiva defensiva)

Las tecnicas de deteccion cubiertas en este laboratorio se alinean con las siguientes tecnicas ATT&CK desde el lado defensivo:

EjercicioTecnica ATT&CKDeteccion
Procesos ocultos (DKOM)T1564.001 (Hidden Files and Directories) / T1014 (Rootkit)Pool scanning vs lista enlazada
SSDT hooksT1574.013 (KernelCallbackTable) / T1014Verificacion de rangos de direcciones
Callbacks maliciososT1543.003 (Windows Service) / T1014Enumeracion de callbacks vs modulos conocidos
Integridad del kernelT1556 (Modify Authentication Process) / T1014Comparacion en memoria vs disco
Carga de driversT1068 (Exploitation for Privilege Escalation) / T1543.003Driver Verifier + breakpoints

Recomendaciones para el laboratorio

Snapshots: Crear un snapshot de la VM target limpia antes de cada experimento. Los rootkits pueden dejar el sistema inestable.

Red aislada: La VM target no debe tener acceso a internet ni a la red local. Configurar una red interna solo entre host y target.

Simbolos offline: Descargar los simbolos necesarios en el host antes de aislar la red. Ejecutar .symfix y .reload /f con conexion a internet, y luego trabajar offline.

Documentacion: Registrar cada sesion de WinDbg con .logopen C:\Logs\session_YYYYMMDD.txt. El log captura todos los comandos y su salida.

No ejecutar rootkits reales fuera del lab: Las tecnicas de este articulo son para entornos controlados. Nunca ejecutar muestras de malware en equipos de produccion o conectados a redes corporativas.

Fuentes y referencias

  • Microsoft: WinDbg Documentation (referencia oficial de comandos y configuracion)
  • Russinovich, M., Solomon, D., Ionescu, A. (2017). Windows Internals Part 1. Microsoft Press. Capitulos 3 (System Mechanisms) y 8 (Security)
  • Matrosov, A., Rodionov, E., Bratus, S. (2019). Rootkits and Bootkits. No Starch Press. Capitulo 14 (WinDbg Kernel Debugging)
  • MITRE ATT&CK: T1014 Rootkit (mapeo de tecnicas defensivas)
  • Microsoft: Driver Verifier (documentacion de verificacion de drivers)

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.