flawopen.com/Teardowns/cve-2014-0160-heartbleed
Detaillierte Zeile-für-Zeile-Patch-Analyse von CVE-2014-0160 (Heartbleed): Die fehlende Grenzprüfung in tls1_process_heartbeat von OpenSSL, die 64 KB Speicher pro Anfrage offenlegte.
Stellen Sie sich vor, Sie schicken einem trainierten Papagei ein 4-Buchstaben-Wort 'BIRD' und sagen: 'Wiederhole mein 4-Buchstaben-Wort, aber mache deine Antwort 64.000 Buchstaben lang'. Der Papagei krächzt 'BIRD' und plappert sofort die nächsten 63.996 Buchstaben aus seinem Kurzzeitgedächtnis heraus – einschließlich geheimer Passwörter, privater Schlüssel und Bankdaten anderer Besucher. Bei Heartbleed vertraute OpenSSL der vom Client behaupteten Nachrichtenlänge, ohne die tatsächliche Paketgröße zu prüfen, und kopierte rohen Serverspeicher direkt zurück zum Angreifer.
Open Source SystemsCWE-SecurityDefense-in-DepthDie Grundursache liegt in nicht validierten Grenzparametern in Open-Source-Systemen, die eine Zustandsdesynchronisation und die Umgehung von Sicherheitskontrollen ermöglichen.
Attacker connects to a TLS server and sends a Heartbeat Request containing a 1-byte payload ('A').
Attacker sets the length field to the maximum possible value: 0xFFFF (65,535 bytes).
The server allocates a 64KB response buffer based on the client's claimed size and calls memcpy().
The memory copy overreads past the end of the packet, dumping private SSL keys, user passwords, and active session tokens.
/* Read 16-bit length directly from client packet without bounds check */
n2s(p, payload);
pl = p;
/* Allocate reply buffer based on client's claimed size */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
/* BUG: Copies up to 64KB of adjacent server heap memory! */
memcpy(bp, pl, payload);
r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
/* Read 16-bit length from packet */
n2s(p, payload);
pl = p;
/* FIX: Validate that claimed payload does not exceed actual received record length */
if (1 + 2 + payload + 16 > s->s3->rrec.length)
return 0; /* Silently discard malformed heartbeat */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
memcpy(bp, pl, payload);
memcpy().:.