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!

sexta-feira, 4 de abril de 2014

DNS Brute Force

Nesta postagem eu vou estar falando um pouco sobre enumeração de DNS através de Brute Force. Eu vou estar apresentando um pequeno script para automatizar o processo de enumeração de subdominios usando Python (pra variar hehe).

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.

Pegando a Wordlist


Para realizar este ataque vamos precisar de uma wordlist com nomes comuns de subdomínios. Uma boa lista de subdomínios pode ser encontrada em http://ethicalhack3r.co.uk/files/fuzzing/subdomains.txt (ver Figura 1).

Figura 1: Lista de Subdomínios

Criando a Ferramenta

 

Vamos criar um pequeno script para automatizar o processo de enumeração DNS (Vamos chamar ele de DnsBrute). O script tem que ser capaz de realizar uma requisição DNS para cada subdominio da wordlist. Vamos utilizar threads para poder agilizar o processo de enumeração.  

O script apresenta um método 'consulta' que realiza as requisições DNS. A variável lista (do tipo Queue) é utilizada pelas threads como base de dados para as requisições realizadas. Enquanto a lista não estiver vazia, a thread gera uma requisição para cada subdomínio presente na lista. A Figura 2 apresenta a implementação das requisições DNS.

Figura 2: Método consulta()

Eu também criei um pequeno menu para o script (ver Figura 3)

Figura 3: DnsBrute.py
Agora podemos utilizar a ferramenta para enumerar os subdomínios de um determinado domínio alvo. A Figura 4 apresenta um exemplo  de execução do script e as respostas obtidas.

Figura 4: DnsBryte.py em execução

Conclusão


Nesta postagem eu apresentei um pequeno script para enumeração de subdomínios através de uma abordagem de Brute Force. O script encontra-se disponível para download em:
 
https://github.com/pasknel/hacking-com-tapioca/blob/master/DNS/DnsBrute.py

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

Obrigado :)

Keep Hacking!