flawopen.com/Teardowns/cve-2014-0160-heartbleed

● CVE-2014-0160 · CVSS 9.8 · 심각
보안 연구 · FlawOpen

심층 기술 분석: CVE-2014-0160: OpenSSL Heartbleed Buffer Overread

CVE-2014-0160(Heartbleed) 소스 코드 패치 심층 분석: OpenSSL의 tls1_process_heartbeat에서 경계 검사 누락으로 요청당 64KB의 서버 메모리가 노출되었던 메커니즘.

💡 알기 쉬운 설명 (ELI5)

훈련된 앵무새에게 4글자 단어 'BIRD'를 전달하며 '내가 보낸 4글자 단어를 따라 하되, 대답의 길이를 64,000글자로 맞춰서 답해줘'라고 요청했다고 상상해 보십시오. 앵무새는 'BIRD'라고 외친 직후, 최근 기억에 남아 있는 다음 63,996글자를 줄줄이 내뱉기 시작합니다. 그 속에는 다른 손님들이 말했던 비밀번호, 암호화 개인 키, 은행 계좌 번호가 고스란히 담겨 있었습니다. Heartbleed 취약점에서 OpenSSL은 실제 수신된 패킷 길이를 검증하지 않고 클라이언트가 주장한 메시지 크기를 그대로 신뢰하여, 서버 메모리에 있던 원시 데이터를 공격자에게 그대로 복사해 전송했습니다.

핵심 개념 및 용어

Open Source Systems
보안 개념 (Open Source Systems): Core architecture component affected by CWE-Security.
CWE-Security
보안 개념 (CWE-Security): Standard Common Weakness Enumeration classification for cve-2014-0160-heartbleed.
Defense-in-Depth
보안 개념 (Defense-in-Depth): Multi-layered engineering verification and runtime boundary isolation.

근본 원인 분석 (Root Cause)

근본 원인은 오픈 소스 시스템의 검증되지 않은 경계 매개변수로 인해 상태 비동기화 및 보안 제어 우회가 발생한 데 있습니다.

단계별 공격 실행 흐름

Step 1

Malformed Heartbeat Request

Attacker connects to a TLS server and sends a Heartbeat Request containing a 1-byte payload ('A').

Step 2

Length Header Manipulation

Attacker sets the length field to the maximum possible value: 0xFFFF (65,535 bytes).

Step 3

Unbounded Heap Buffer Allocation

The server allocates a 64KB response buffer based on the client's claimed size and calls memcpy().

Step 4

Adjacent Memory Exfiltration

The memory copy overreads past the end of the packet, dumping private SSL keys, user passwords, and active session tokens.

소스 코드 비교: 취약한 구현 vs 보안 패치

✕ 취약한 구현
/* 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);

엔지니어링 및 시스템 보안 강화 체크리스트