A não ser que você esteja vivendo em uma caverna pelos ultimos dias, é muito provavel que você ja tenha ouvido falar sobre uma nova vulnerabilidade identificada no OpenSSL (referenciada como CVE-2014-0160). Nesta postagem eu vou estar analisando esta vulnerabilidade e também alguns códigos de PoC que ja podem ser encontrados publicamente disponíveis.
O
conteúdo apresentado nesta postagem deve ser reproduzido apenas em um
ambiente no qual você possui autorização para a realização de testes de
segurança.
SSL: Heartbeat message
Nós precisamos começar falando sobre um tipo específico de mensagem utilizada pelo SSL: Heartbeat message. A vulnerabilidade do OpenSSL ocorre exatamente na maneira pela qual esta mensagem é tratada. Vamos começar analisando a estrutura desse tipo de mensagem.
O 'Heartbeat' é definido no RFC 6520 e apresenta a seguinte estrutura:
![]() | ||
Figura 01: Mensagem 'Heartbeat' (RFC 6520) |
A mensagem é formada por 4 campos:
- Campo 'type': Tipo da mensagem (requisição ou resposta)
- Campo 'payload_length': Tamanho do payload
- Campo 'payload': Payload da mensagem (dados arbitrários)
- Campo 'padding': Bytes extras de padding
Analisando o Bug
A vulnerabilidade encontra-se em d1_both.c (função dtls1_process_heartbeat) do OpenSSL. O código é chamado durante o processamento de requisições heartbeat (A Figura 02 apresenta o código vulnerável).
![]() |
Figura 02: Código vulnerável (d1_both.c) |
O tamanho de um buffer é definido a partir da variável 'payload' (do tipo unsigned int). Esta variável apresenta o valor do campo 'payload_length' do cabeçalho da mensagem de requisição heartbeat. É importante notar de que não existe nenhuma verificação sobre o valor (tamanho) presente na variável payload.
Analisando os primeiros PoC
Nesta seção eu vou estar analisando um dos código que eu encontrei disponíveis publicamente para download (https://gist.githubusercontent.com/takeshixx/10107280/raw/8052d8479ad0c6150464748d639b0f5e877e8c37/hb-test.py).
Este código cria uma conexão para um determinado alvo e envia 2 pacotes (variáveis 'hello' e 'hb'). Eu criei um pequeno script (utilizando scapy) para recriar os pacotes (especialmente o 'hb') para podermos analisar melhor no wireshark (Ver figura 03).
![]() |
Figura 03: Recriando pacotes para análise |
O meu pequeno script recriou os pacotes originais e salvou eles em um arquivo (heartbleed.pcap). A Figura 04 apresenta a análise dos pacotes no wireshark.
![]() |
Figura 04: Analisando requisição heartbeat |
É importante notar que a requisição heartbeat apresenta um valor de 16384 (0x4000) no campo 'payload_length' mas não apresenta payload na mensagem! O valor de 'payload_length' vai ser utilizado para definir o tamanho do buffer na função dtls1_process_heartbeat (d1_both.c). Como não existe payload, o buffer vai ser completado com valores na memória do processo.
Explorando a vulnerabilidade
Vamos agora rodar o script contra um servidor vulnerável (utilizei um serviço com SSL na minha própria máquina virtual para fazer o teste). A Figura 05 apresenta o script em execução.
![]() |
Figura 05: Explorando a vulnerabilidade |
Através da figura 05, é possível ver o pedaço de um dump de memória do processo (o qual mostra o Token de acesso utilizado por um usuário da aplicação alvo). O meu serviço estava rodando TLS 1.0 por isso eu tive que trocar os bytes "03 02" (TLS 1.1) dos pacotes 'hello' e 'hb' para "03 01" (vocês podem fazer essa troca manualmente no script).
Conclusão
Nesta postagem eu fiz uma análise sobre a vulnerabilidade CVE-2014-0160 encontrada no OpenSSL. Vocês podem utilizar estas informações para verificar se os seus servidores estão vulneráveis a este tipo de ataque.
Obrigado :)
Keep Hacking!