Parte: 5 — Explotación de sistemas y binarios · Fuente: Erickson, Hacking 2e · Aleph One, "Smashing the Stack" ⏱️ Duración estimada: 100 min · Nivel: Intermedio
Entender con precisión por qué y cómo un buffer overflow en el stack corrompe la dirección
de retorno y permite secuestrar el flujo de ejecución. Esta clase es teórica: sienta el modelo mental
(layout de memoria, escritura fuera de límites, control de RIP) que aplicarás prácticamente en la
clase 120. Sin este mapa conceptual, la explotación es prueba y error a ciegas.
Al finalizar, el alumno podrá:
RIP.gets, strcpy, sprintf, scanf %s).| # | Tema | Por qué importa |
|---|---|---|
| 1 | Buffers en el stack | Dónde se guardan y su tamaño fijo |
| 2 | Escritura fuera de límites | La causa raíz del bug |
| 3 | Sobrescritura de saved RBP y ret | Camino hacia el control de RIP |
| 4 | Concepto de offset | Cuántos bytes hasta el retorno |
| 5 | Control de RIP → control de flujo | El objetivo del exploit |
| 6 | Funciones peligrosas de C | Dónde nacen estos bugs |
| 7 | Impacto y variantes | Local vs remoto, DoS vs RCE |
| 8 | Panorama de mitigaciones | Por qué hoy no basta lo básico |
tamaño_buffer + padding + saved RBP.win(), o una cadena ROP.gets, strcpy, strcat, sprintf). Clave:
sus versiones acotadas (fgets, strncpy, snprintf) mitigan el problema.nop que amplía el margen de acierto al saltar a shellcode.
Clave: útil cuando la dirección exacta es incierta.Esta clase es conceptual, pero conviene tener listos GDB+pwndbg (clase 118) y un editor. Prepara un
diagrama en papel o en un .md del stack para razonar los offsets.
# Repasa las protecciones que trae un binario cualquiera:
checksec --file=/bin/ls # instalar: pip install pwntools (trae checksec)
Ejercicio conceptual-aplicado (sin lanzar exploit todavía).
Toma el binario vuln de la clase 118 y ábrelo en pwndbg.
Desensambla vuln y anota el tamaño del frame que reserva el prólogo (sub rsp, 0x50 → 80 bytes). Ojo: eso no es el tamaño del buffer. El buffer vive en [rbp-0x40] (64 bytes); el offset desde su inicio hasta la dirección de retorno es 64 + 8 (RBP guardado) = 72, el valor que confirmarás con cyclic (coherente con las clases 118 y 120).
Dibuja en papel el frame de vuln de arriba (direcciones altas) a abajo:
text
[ ret address ] <- rbp+8 (objetivo)
[ saved RBP ] <- rbp
[ buf[63..0] ] <- rbp-0x40 ... crece hacia rbp
Calcula el offset teórico al retorno y contrástalo con el valor que hallaste con cyclic en la 118.
Identifica en el código fuente qué función provoca el overflow (gets) y qué la haría segura (fgets).
Ejecuta checksec ./vuln y anota qué mitigaciones están desactivadas (NX, canary, PIE) y por qué
eso hace el binario explotable — lo aprovecharás en la clase 120.
Escribe un breve informe (5-8 líneas) explicando la cadena causa→efecto del bug.
strncpy(dst, src, sizeof(dst)) no siempre es seguro (terminación nula).Redacta y entrega un diagrama del stack frame de vuln con offsets numéricos exactos y una frase
que indique cuántos bytes hay que escribir para alcanzar (sin sobrescribir aún) la dirección de retorno.
Criterio de aceptación: el offset del diagrama coincide con el que confirma cyclic -l en GDB, y
señalas correctamente la posición de saved RBP y ret address.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| Offset calculado ≠ real | Olvidaste el saved RBP (8 bytes) o el padding de alineación |
| "Mi overflow no controla RIP" | Hay stack canary; lo verás en checksec (clase 122) |
| Confundir dirección alta/baja | El stack crece hacia abajo; dibújalo siempre |
Creer que strncpy es infalible |
Puede dejar la cadena sin \0; revisa longitudes |
| Pensar que todo overflow = RCE | Muchos solo causan crash/DoS; depende del control logrado |
❓ ¿Por qué sobrescribir el retorno y no otra cosa? Porque ret carga esa dirección en RIP
directamente, dándote control de flujo sin trucos adicionales.
❓ ¿Esto sigue funcionando en binarios modernos? No tal cual: canarios, NX, ASLR y PIE lo complican. Por eso primero se estudia en un binario sin protecciones.
❓ ¿Es lo mismo overflow en stack que en heap? No; el heap tiene metadatos y mecánica distinta (clases 126-127).
Clase 118 — Debugging con GDB y pwndbg