\n\n\n\n\n\n\n\n\n\n\n

flawopen.com/시뮬레이터/Heartbleed 버퍼 오버리드

메모리 안전성 / OpenSSL TLS

OpenSSL Heartbleed 버퍼 오버리드 대화형 시뮬레이터 (CVE-2014-0160)

브라우저에서 직접 실행되는 메모리 모델 시뮬레이터: 검증되지 않은 TLS Heartbeat 길이 필드가 서버 힙 메모리 유출(Buffer Overread)을 초래하는 과정을 시각화합니다.

💡 쉬운 비유 설명 (ELI5)

훈련된 앵무새에게 4글자 단어 'BIRD'를 건네며 '내가 말한 단어를 반복하되, 총 64,000글자로 길게 대답해줘'라고 요구하는 상황을 상상해 보세요. 앵무새는 'BIRD'라고 외친 뒤, 자신의 최근 기억 속에 남아 있던 다음 63,996자의 내용—다른 손님들의 비밀번호, 개인 암호키, 계좌번호 등—을 줄줄 읊기 시작합니다. 하트블리드(Heartbleed) 취약점에서도 OpenSSL은 실제 수신된 패킷 길이를 확인하지 않고 클라이언트가 주장한 길이를 그대로 신뢰하여, 서버의 민감한 힙 메모리를 공격자에게 그대로 복사해 전송했습니다.

핵심 개념 및 하위 시스템 용어

TLS Heartbeat 확장
RFC 6520에 규정된 세션 재협상 없는 보안 연결 유지(Keep-Alive) 메커니즘.
\n
Payload Length 필드
하트비트 헤더에 포함된 16비트 부호 없는 정수로, 페이로드 바이트 크기를 선언(최대 65,535바이트).
\n
Buffer Overread
할당된 버퍼 경계를 초과하여 인접한 프로세스 메모리를 읽어내는 메모리 안전 취약점.
\n
경계 미검증 memcpy()
클라이언트가 지정한 길이를 실제 수신 레코드 크기와 대조하지 않고 수행하는 메모리 복사 작업.

단계별 익스플로잇 및 취약점 실행 흐름

1

조작된 Heartbeat 요청 패킷 전송

공격자는 단 1바이트('A')의 페이로드만 전송하면서 길이 필드는 65,535바이트(0xFFFF)로 조작.

\n
2

패킷 길이 경계 검증 누락

OpenSSL은 n2s(p, payload)로 길이를 읽어들이지만, 1 + 2 + payload + 16 <= rrec.length 여부를 검증하지 않음.

\n
3

64KB 응답 버퍼 과다 할당

서버는 공격자의 주장을 신뢰하여 힙에 64KB 크기의 응답 버퍼를 할당.

\n
4

버퍼 오버리드로 민감 메모리 유출

memcpy()가 1바이트 패킷을 넘어 인접 힙 메모리를 복사하여 RSA 개인키와 세션 쿠키를 공격자에게 전송.

소스 코드 비교: tls1_process_heartbeat()의 경계 검증

미패치 취약점: OPENSSL 1.0.1f의 페이로드 경계 검증 누락
/* 패킷 경계 검증 없이 16비트 길이를 직접 읽음 */
n2s(p, payload);
pl = p;

/* 클라이언트가 주장한 크기를 바탕으로 응답 버퍼 할당 */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;

/* 치명적 결함: 서버 힙 인접 메모리를 최대 64KB까지 복사! */
memcpy(bp, pl, payload);
r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
보안 패치: 수신된 실제 레코드 크기 기반 엄격한 경계 검증 (RFC 6520)
/* 패킷에서 16비트 길이 추출 */
n2s(p, payload);
pl = p;

/* 패치: 선언된 페이로드가 실제 수신된 레코드 크기를 초과하지 않는지 검증 */
if (1 + 2 + payload + 16 > s->s3->rrec.length)
    return 0; /* 비정상적인 하트비트 패킷을 조용히 폐기 */

buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
memcpy(bp, pl, payload);

엔지니어링 보안 점검 체크리스트

← 모든 시뮬레이터 CVE-2014-0160 Heartbleed 기술 분석 상세 보기 →