sábado, 12 de abril de 2014

My Heart Bleeds For You: Analisando OpenSSL Bug

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.

Observação:

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:
  1. Campo 'type': Tipo da mensagem (requisição ou resposta)
  2. Campo 'payload_length': Tamanho do payload
  3. Campo 'payload': Payload da mensagem (dados arbitrários)
  4. 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.

Por favor escrevam suas sugestões e comentários!

Obrigado :)

Keep Hacking!

Um comentário: