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

● CVE-2014-0160 · CVSS 9.8 · Crítica
Pesquisa · FlawOpen

CVE-2014-0160: OpenSSL Heartbleed Buffer Overread

Análise técnica linha por linha do patch da CVE-2014-0160 (Heartbleed): a verificação de limites ausente no tls1_process_heartbeat do OpenSSL que expunha 64 KB de memória por requisição.

💡 Explicação em Linguagem Simples (ELI5)

Imagine enviar uma única palavra de 4 letras 'BIRD' para um papagaio treinado e dizer: 'Repita minha palavra de 4 letras, mas faça sua resposta ter 64.000 letras'. O papagaio grasna 'BIRD' e imediatamente começa a tagarelar as 63.996 letras seguintes armazenadas em sua memória recente — incluindo senhas secretas, chaves privadas e números bancários de outros visitantes. No Heartbleed, o OpenSSL confiava no tamanho declarado da mensagem sem verificar o comprimento real do pacote, copiando a memória do servidor diretamente de volta ao invasor.

Conceitos Centrais e Termos

Open Source Systems
Componente de arquitetura principal afetado pelo CWE-Security.
CWE-Security
Classificação padrão Common Weakness Enumeration (CWE) para cve-2014-0160-heartbleed.
Defense-in-Depth
Verificação de engenharia em múltiplas camadas e isolamento de limites em tempo de execução.

Análise de Causa Raiz

A causa raiz decorre de parâmetros de limite não validados em sistemas de código aberto, permitindo a dessincronização de estado e a evasão dos controles de segurança.

Fluxo de Ataque Passo a Paso

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.

Código-Fonte: Vulnerável vs. Seguro

✕ IMPLEMENTAÇÃO VULNERÁVEL
/* 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);
✓ PATCH SEGURO E ROBUSTO
/* 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);

Lista de Verificação de Segurança para Engenharia