flawopen.com/Teardowns/cve-2014-0160-heartbleed
Analisis patch baris demi baris dari CVE-2014-0160 (Heartbleed): pemeriksaan batas yang hilang di tls1_process_heartbeat OpenSSL yang mengekspos 64KB memori server per permintaan.
Bayangkan mengirimkan satu kata 4 huruf 'BIRD' ke burung beo terlatih dan berkata: 'Ulangi kata 4 huruf saya, tetapi buat jawaban Anda sepanjang 64.000 huruf'. Burung beo itu berkicau 'BIRD' dan segera mulai mengoceh 63.996 huruf berikutnya yang tersimpan dalam ingatan terbarunya—termasuk kata sandi rahasia, kunci privat, dan nomor rekening pengunjung lain. Dalam Heartbleed, OpenSSL mempercayai panjang pesan yang diklaim klien tanpa memeriksa ukuran paket sebenarnya, menyalin memori mentah server langsung kembali ke penyerang.
Open Source SystemsCWE-SecurityDefense-in-DepthAkar masalah bermula dari parameter batas yang tidak divalidasi pada sistem open source, yang memungkinkan desinkronisasi status dan bypass kontrol keamanan.
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().:.