\n\n\n\n\n\n\n\n\n\n\n
flawopen.com/Simulateurs/Heartbleed Buffer Overread
Simulateur de mémoire interactif dans le navigateur démontrant comment les champs de longueur TLS Heartbeat non validés provoquent une lecture hors limites dans le tas du serveur.
Imaginez envoyer un mot de 4 lettres 'BIRD' à un perroquet savant en lui disant : 'Répète mon mot, mais fais une réponse longue de 64 000 lettres'. Le perroquet crie 'BIRD' puis enchaîne immédiatement en débitant les 63 996 lettres suivantes stockées dans sa mémoire récente — y compris les mots de passe secrets, les clés de chiffrement privées et les données bancaires d'autres visiteurs. Avec Heartbleed, OpenSSL faisait confiance à la longueur annoncée par le client sans vérifier la taille réelle du paquet, renvoyant la mémoire brute du serveur à l'attaquant.
L'attaquant initie une requête TLS Heartbeat contenant 1 octet ('A') avec un champ de longueur réglé sur 65 535 octets (0xFFFF).
OpenSSL lit la longueur via n2s(p, payload) sans vérifier si 1 + 2 + payload + 16 <= rrec.length.
Le serveur alloue 64 Ko en mémoire d'après l'affirmation du client et initialise l'en-tête de réponse.
L'appel memcpy() copie 64 Ko au-delà du paquet de 1 octet, exposant les clés privées SSL et les cookies de session.
/* Lecture directe de la taille sur 16 bits sans vérification */
n2s(p, payload);
pl = p;
/* Allocation du tampon de réponse selon la taille déclarée */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
/* ERREUR : Copie jusqu'à 64 Ko de mémoire adjacente du tas ! */
memcpy(bp, pl, payload);
r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
/* Lecture de la taille sur 16 bits */
n2s(p, payload);
pl = p;
/* CORRECTIF : Vérifier que la charge déclarée ne dépasse pas la taille réelle reçue */
if (1 + 2 + payload + 16 > s->s3->rrec.length)
return 0; /* Ignorer silencieusement le paquet malformé */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
memcpy(bp, pl, payload);