
Laboratorio autocontenido de Heartbleed (CVE-2014-0160): compila OpenSSL 1.0.1f vulnerable en Docker e incluye un PoC en Python de fuga de memoria para pruebas autorizadas.
Un laboratorio pequeño y autocontenido para CVE-2014-0160 (Heartbleed) — la sobrelectura del heartbeat de TLS en OpenSSL 1.0.1–1.0.1f. Compila el OpenSSL genuinamente vulnerable a partir del código fuente upstream fijado en un contenedor desechable, lo sirve e incluye un cliente de prueba de concepto que filtra memoria viva del proceso desde él.
Solo para uso autorizado en laboratorio. Todo aquí apunta a
localhost/ un contenedor que tú mismo ejecutas. No apuntes el PoC a ningún host que no poseas y para el que no tengas permiso explícito de probar — el uso no autorizado de Heartbleed contra sistemas en producción es un delito en la mayoría de jurisdicciones. Heartbleed se corrigió en OpenSSL 1.0.1g (abril de 2014); este laboratorio existe para entender el fallo, no para atacar a nadie.
| Ruta | Qué es |
|---|---|
Dockerfile | Compila OpenSSL 1.0.1f desde el código fuente upstream fijado por checksum con los heartbeats habilitados, genera un certificado desechable y ejecuta openssl s_server — el servidor vulnerable real. |
exploit/heartbleed.py | PoC en Python 3. Envía un heartbeat malformado y hace un hexdump de la memoria que el servidor filtra de vuelta. Sale con 0 si el objetivo es vulnerable, 1 si está parcheado. |
demo/server.py | Una simulación ingenua en Python puro — sin OpenSSL involucrado. Devuelve ciegamente 64 KB y no filtra nada real; se mantiene solo para mostrar la forma de una respuesta de sobrelectura. |
demo/gen-cert.sh | Regenera el certificado desechable de localhost para la demo. |
No se incluye ninguna clave privada — los certificados se generan localmente (ver .gitignore).
# 1. Build and start the vulnerable server (needs Docker)
docker build -t heartbleed-lab .
docker run --rm -p 8443:8443 heartbleed-lab
# 2. In another terminal, bleed it
python3 exploit/heartbleed.py 127.0.0.1 -p 8443
Un servidor vulnerable imprime un hexdump de la memoria filtrada. Vuelve a ejecutar el PoC unas cuantas veces — cada petición devuelve una porción distinta del heap, que es exactamente por lo que Heartbleed era tan peligroso: cookies de sesión, datos de formularios y material de clave privada viven todos ahí.
cd demo
./gen-cert.sh
python3 server.py
Esto no es el CVE — es un stub didáctico que siempre responde con 64 KB de As.
La petición de heartbeat de TLS lleva un payload más un campo de longitud. El OpenSSL vulnerable confía en la longitud proporcionada por el atacante y hace memcpy de esa cantidad de bytes desde el búfer de la petición hacia la respuesta — pero la petición nunca contuvo tantos datos, así que la copia lee más allá de ella hacia cualquier memoria adyacente del proceso que haya. La corrección en 1.0.1g es una comprobación de límites: if (1 + 2 + payload + 16 > s->s3->rrec.length) return 0; — descartar silenciosamente cualquier heartbeat que afirme más de lo que realmente se envió.
-DOPENSSL_NO_HEARTBEATS.