\n\n\n\n\n\n\n\n\n\n\n
flawopen.com/Simuladores/Heartbleed Buffer Overread
Simulador interactivo de memoria en el navegador que demuestra cómo los campos de longitud no validados en TLS Heartbeat provocan lecturas fuera de límites en la memoria heap del servidor.
Imagine enviar una sola palabra de 4 letras 'BIRD' a un loro entrenado y decirle: 'Repite mi palabra, pero haz que tu respuesta tenga 64.000 letras'. El loro dice 'BIRD' y de inmediato comienza a repetir las siguientes 63.996 letras almacenadas en su memoria reciente, incluyendo contraseñas secretas, claves privadas de cifrado y mensajes de otros clientes. En Heartbleed, OpenSSL confiaba en la longitud declarada por el cliente sin verificar el tamaño real del paquete, enviando la memoria privada del servidor al atacante.
El atacante conecta al servidor TLS y envía un Heartbeat con 1 byte de carga ('A'), declarando una longitud de 65.535 bytes (0xFFFF).
OpenSSL extrae la longitud mediante n2s(p, payload) sin verificar si 1 + 2 + payload + 16 <= rrec.length.
El servidor reserva 64 KB de memoria de respuesta basándose únicamente en la afirmación del cliente.
La función memcpy() lee 64 KB continuos más allá del paquete de 1 byte, extrayendo claves SSL privadas y tokens de autenticación.
/* Lee longitud de 16 bits directamente sin validar límites */
n2s(p, payload);
pl = p;
/* Asigna búfer de respuesta según la longitud declarada por el cliente */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
/* FALLO: ¡Copia hasta 64 KB de memoria contigua del heap! */
memcpy(bp, pl, payload);
r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
/* Lee longitud de 16 bits del paquete */
n2s(p, payload);
pl = p;
/* REFUERZO: Validar que la carga útil declarada no supere el paquete real recibido */
if (1 + 2 + payload + 16 > s->s3->rrec.length)
return 0; /* Descarta silenciosamente el paquete malformado */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
memcpy(bp, pl, payload);