flawopen.com/Teardowns/cve-2014-0160-heartbleed
CVE-2014-0160(Heartbleed) 소스 코드 패치 심층 분석: OpenSSL의 tls1_process_heartbeat에서 경계 검사 누락으로 요청당 64KB의 서버 메모리가 노출되었던 메커니즘.
훈련된 앵무새에게 4글자 단어 'BIRD'를 전달하며 '내가 보낸 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().:.