Heartbleed – Vulnerabilidade OpenSSL

 1ª Parte

A OpenSSL lançou um aviso de bug sobre um patch de vazamento de memória 64kb em sua biblioteca . O erro foi atribuído, como  Heartbleed -TLS CVE – 2014-0160.

De acordo com o OpenSSL , a extensão Heartbleed  foi introduzido em Março de 2012 com o lançamento da versão 1.0.1 do OpenSSL. Isto implica que a vulnerabilidade está presente em torno de pouco mais de 2 anos. Essa é uma vulnerabilidade muito grave que permitirá que informações protegidas possam ser roubadas , mesmo com o uso de criptografia SSL / TLS.

Desde o anúncio , houve rumores no meio undergroud e atores maliciosos sobre o vazamentos ativamente de dados da biblioteca de software e como usar várias parte do código PoC fornecido para atacar uma enorme quantidade de serviços disponíveis na internet.

Apenas as versões 1.0.1 e 1.0.2- beta versões do OpenSSL são afetados incluindo 1.0.1f e 1.0.2 -beta1 . Os alvos são principalmente a porta 443 . Com isso, um atacante é capaz de vazar dados previamente alocados. Isso não inclui as credenciais de texto simples , cookies de sessão , chaves privadas para descriptografar ( arbitrariamente comunicação SSL / TLS) , e muito mais . O OpenSSH não parecem ser suscetíveis à vulnerabilidade como OpenSSL, No entanto o  OpenSSL  é usado para geração de chaves , mas não de comunicação.

O site Heartbleed.com menciona uma ferramenta baseada na web e um conjunto de  scripts para testar e verificar se você está vulnerável a este último exploit :

1 – Um teste baseado na web.

Link: http://filippo.io/Heartbleed/

2 – Um script Python para testar a vulnerabilidade a partir da linha de comando. Se você quiser incluir vários sites, você pode usar uma versão modificada com uma saída facilmente analisável .

Link: http://docs.google.com/file/d/0Bw4_BgIkljcbRjZkZ2VDMmpiVnM/edit?pli=1

Este post tem feito um excelente trabalho explicando , em código , exatamente o que aconteceu e o que a vulnerabilidade é exatamente. Agora, como um atacante com PoC simples , isso é o que somos capazes de fazer:

1. while [ 1 ]; do python poc.py server.com 443; done
2. ngrep -i “password_field_value” -d any host victim.org and port 443 -q

Isso nos permite spam do PoC para dados recentemente alocados e usar ngrep para pegar o campo em que as senhas estão sendo enviadas, o diâmetro. Usando estes dois comandos , temos sido capazes de capturar uma grande quantidade de senhas entregues https,  como texto simples . Como você pode ver , isso quebra uma grande variedade de aplicações web que incluem e-mails on-line ( yahoo ) , bancos e uma grande variedade de outros alvos.

Uma das questões mais complicadas é que os patches OpenSSL não estavam atualizados com o montante de grandes distribuições de Linux . Significando que havia uma grande janela de tempo entre a correção do OpenSSL e quando várias distribuições  de Linux podem fornecer o patch para a sua base de usuários. O site OpenSSL.org forneceu uma versão atualizada do OpenSSL ( 1.0.1g ). Depois de atualizar para a versão mais recente você deve, então, regenerar a sua chave privada (s) e certificado (s) SSL. Também é  recomendado redefinir todas as senhas de nomes de usuário que foram usados durante o período de tempo que você estava vulnerável.

Tivemos uma oportunidade de rever o comportamento da exploração e ver as seguintes assinaturas IDS serem implantadas para a detecção.

alert tcp !$HOME_NET any -> $HOME_NET 443 (msg:”SSLv3 OpenSSL Heartbeat Memory Leak”; content:”|18 03 00|”; depth:3; byte_test:2,>,199,3; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid:1006054; tag:session,5,packets; rev:1;)

alert tcp !$HOME_NET any -> $HOME_NET 443 (msg:”TLSv1 OpenSSL Heartbeat Memory Leak”; content:”|18 03 01|”; depth:3; byte_test:2,>,199,3; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid:1006055; tag:session,5,packets; rev:1;)

alert tcp !$HOME_NET any -> $HOME_NET 443 (msg:”TLSv1.1 OpenSSL Heartbeat Memory Leak”; content:”|18 03 02|”; depth:3; byte_test:2,>,199,3; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid:1006056; tag:session,5,packets; rev:1;)

alert tcp !$HOME_NET any -> $HOME_NET 443 (msg:”TLSv1.2 OpenSSL Heartbeat Memory Leak”; content:”|18 03 03|”; depth:3; byte_test:2,>,199,3; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid:1006057; tag:session,5,packets; rev:1;)

By: Stephen Coty, Chief Security Evangelist at Alert Logic.

2ª Parte 

O bug Heartbleed é um bug particularmente desagradável. Ele permite que um invasor leia até 64KB de memória, e os pesquisadores de segurança notificam:

Sem o uso de qualquer informação privilegiada ou credenciais podemos roubar as chaves secretas usadas para os nossos certificados X.509, nomes de usuário e senhas, mensagens instantâneas, e-mails e documentos críticos de negócios e comunicações.

O Bug

A correção começa aqui, em ssl/d1_both.c:

int            
dtls1_process_heartbeat(SSL *s)
    {          
    unsigned char *p = &s->s3->rrec.data[0], *pl;
    unsigned short hbtype;
    unsigned int payload;
    unsigned int padding = 16; /* Use minimum padding */
 

Então, primeiro temos um ponteiro para os dados dentro de um registro SSLv3. Que se parece com isso:


typedef struct ssl3_record_st
    {
        int type;               /* type of record */
        unsigned int length;    /* How many bytes available */
        unsigned int off;       /* read/write offset into 'buf' */
        unsigned char *data;    /* pointer to the record data */
        unsigned char *input;   /* where the decode bytes are */
        unsigned char *comp;    /* only used with decompression - malloc()ed */
        unsigned long epoch;    /* epoch number, needed by DTLS1 */
        unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
    } SSL3_RECORD;

Registros tem um tipo, um tamanho e dados. Voltar para dtls1_process_heartbeat:

/* Read type and payload length first */
hbtype = *p++;
n2s(p, payload);
pl = p;

O primeiro byte do registro SSLv3 é o tipo de heartbeat . Os macro n2s leva dois bytes de p , e coloca-os em payload. Isto é , na verdade, o tamanho da carga . Note-se que o comprimento real no registro SSLv3 não está marcada.

A variável pl  é, então, os dados de heartbeat (batimentos cardíacos) resultantes, fornecidos pelo solicitante.

Mais tarde, na função , ele faz isso :

 

unsigned char *buffer, *bp;

int r;

/* Allocate memory for the response, size is 1 byte
 * message type, plus 2 bytes payload length, plus
 * payload, plus padding
 */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;

Então, nós estamos alocando mais memória que o solicitante pediu : até 65535 +1 +2 +16, para ser preciso. A variável bp vai ser o ponteiro usado para acessar essa memória . Então:


/* Enter response type, length and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);

A macro s2n faz o inverso da n2s: é preciso um valor de 16 bits e coloca-lo em dois bytes. Por isso, coloca o mesmo tamanho de carga requerida .

Em seguida, ele copia os bytes de carga útil de pl, o usuário forneceu dados para a matriz bp recém-alocado . Depois disso, ele envia esta tudo de volta para o usuário. Então, onde está o erro ?

O usuário controla payload e pl

E se o solicitante não chegou a fornecer bytes de carga útil , como ele disse que ele fez ? E se pl realmente é apenas um byte ? Em seguida, a leitura de memcpy vai ler o que a memória tinha perto do registro de SSLv3 e dentro do mesmo processo .

E, aparentemente , há um monte de coisas nas proximidades.

Há duas formas de memória a que é alocada dinamicamente com malloc (pelo menos no Linux) : usando sbrk (2) e utilizando mmap (2). Se a memória é alocada com sbrk , então ele usa as regras heap-grows-up e limita o que pode ser encontrado com este, apesar de vários pedidos (especialmente em simultâneo) ainda pode encontrar um pouco de diversão stuff1 .

As alocações para bp , não importa em tudo , na verdade.  A alocação para pl , no entanto, tem uma grande importância . É quase certo alocado com sbrk por causa do limite de mmap em malloc . No entanto, coisas interessantes (como documentos ou informações do usuário ) , é muito provável serem alocada com mmap e pode ser acessado a partir de pl . Várias solicitações simultâneas também deixará alguns dados interessantes disponíveis .

Então o que isso significa? Bem, os padrões de alocação para pl vão informar o que você pode ler . Aqui está o que um dos descobridores da vulnerabilidade tinha a dizer sobre isso :

A correção

A parte mais importante da correção foi esta:

/* Read type and payload length first */
if (1 + 2 + 16 > s->s3->rrec.length)
    return 0; /* silently discard */
hbtype = *p++;
n2s(p, payload);
if (1 + 2 + payload + 16 > s->s3->rrec.length)
    return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;

Isto faz duas coisas : a primeira verificação verifica batimentos cardíacos de comprimento zero . A segunda verificação verifica para certificar-se que o comprimento do registro real é suficientemente longa . É isso aí.


Lições

O que podemos aprender com isso?

Eu sou um fã de C. Foi a minha primeira linguagem de programação e que foi a primeira língua que eu me senti confortável usando profissionalmente. Mas eu vejo suas limitações mais claramente agora do que alguma vez antes.

Entre este e o bug GnuTLS*, eu acho que nós precisamos de fazer três coisas:

1 – Pagar dinheiro para auditorias de infra-estrutura crítica de segurança como segurança OpenSSL;

2- Escrever um monte de testes de unidade e de integração para essas bibliotecas;

3 – Começar a escrever em línguas alternativas mais seguras;

Devido como é difícil escrever em C, de forma segura, não vejo nenhuma outra opção. Eu doaria para este esforço. Você faria isso?.

By: Neel Mehta

Nota: BUG – GnuTLS

Uma variedade de distribuições Linux estão vulneráveis a hacks por causa de um bug que permite que as pessoas possam contornar os protocolos de segurança para interceptar e disseminar informações criptografadas . Um membro da equipe de segurança do Red Hat descobriu um bug na biblioteca GnuTLS que permite que hackers contornem facilmente a Transport Layer Security (TLS) e Secure Sockets Layer (SSL).

A vulnerabilidade afeta a verificação do certificado , ou seja, conexões seguras que são supostamente passadas por seguras , não são . Alguém poderia comprometer uma conexão segura usando um ataque ” man-in -the-middle ” , atuando como um servidor para interceptar o tráfego , transações financeiras ou informações seguras.

A Apple sofreu com sua própria falha , na semana passada , quando os pesquisadores descobriram uma vulnerabilidade crítica de segurança que permitia que hackers pudessem enganar os servidores e interceptar dados supostamente seguros de servidores da Apple . Em termos de número de usuários afetados , a falha GnuTLS é consideravelmente menor do que o erro da Apple , o que afetou os dispositivos iOS e Mac da mesma forma, mas remendar a vulnerabilidade GnuTLS para todos os usuários de Linux será mais difícil .

 

Fontes: http://www.net-security.org/secworld.php?id=16661

                 http://www.alertlogic.com/ssltls-heartbeat-read-overrun-aka-64kb-memory-leak-cve-2014-0160/

                 http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html

                 http://news.netcraft.com/archives/2014/04/08/half-a-million-widely-trusted-websites-vulnerable-to-heartbleed-bug.html

                 http://readwrite.com/2014/03/05/gnutls-bug-linux-security-flaw-leaves-users-vulnerable-hacks#awesm=~oB8ZFD2IqHA7ab