flawopen.com/Teardowns/cve-2014-0160-heartbleed
CVE-2014-0160(Heartbleed)のソースコードパッチ詳細解説:OpenSSLの tls1_process_heartbeat における境界チェック欠落により、リクエストごとに64KBのサーバーメモリが漏洩したメカニズム。
訓練されたオウムに「BIRD」という4文字の単語を送り、「この4文字の単語を復唱して。ただし返答は64,000文字の長さにしてね」と伝えたとします。オウムは「BIRD」と鳴いた後、直近の記憶に残っている次の63,996文字をペラペラと喋り始めます。そこには他の訪問者が話した秘密のパスワード、暗号秘密鍵、銀行口座番号が含まれていました。Heartbleedでは、OpenSSLがパケットの実際の長さを検証せず、クライアントが申告したデータ長を鵜呑みにしたため、サーバーの生メモリが攻撃者へそのまま漏洩しました。
Open Source SystemsCWE-SecurityDefense-in-Depth根本原因は、オープンソースシステムにおける未検証の境界パラメータに起因し、状態の非同期化とセキュリティ制御の迂回を可能にします。
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().:。