Heartbleed - a estrambólica hemorragia cardíaca causadora da falha de segurança no OpenSSL

"O computador sempre vai fazer exatamente o que você diz – nada a menos, e nada a mais. Ele é obediente, mas nem sempre é esperto – então você (ou o programador) precisa ser".


Hoje ao ler as matérias sobre o Heartbleed, a notícias mais “punk” da semana, pois apontou uma grave falha de segurança no OpenSSL, me bateu uma saudade das aulas de lógica de programação, C, algoritmos enfim de todas as loucuras que aprendi no curso de Ciência da Computação. Aliás, abre parêntese - só louco faz um curso desses e aguenta chegar até o final e se formar – fecha parêntese.

Transcrevo resumo do texto que li no MSN, por considerar o mais didático e ao mesmo tempo técnico.

Então vamos lá, Heartbleed, é falha de segurança que pode expor inúmeras transações criptografadas para qualquer hacker que souber usá-la. OK, mas como isto realmente funciona? Na verdade, é muito simples – e por isso tão alarmante.
Em termos gerais, o Heartbleed é uma falha no OpenSSL, software que permite ao seu computador e a um servidor saberem que são quem dizem que são. Ele deixou grandes sites – como Yahoo, Flickr e Imgur – vulneráveis a roubo de dados por anos, desde 2011. É algo bem assustador, e merece um olhar mais atento.

A beleza de um projeto de código aberto como o OpenSSL é que qualquer um pode olhar o código; não há como esconder algo de propósito. Na verdade, você pode ver exatamente onde o Heartbleed nasceu e onde foi consertado, mesmo que não entenda muito de código.

Por isso, é tão surpreendente como o Heartbleed passou despercebido por tanto tempo. Dois anos se escondendo à vista de todos, sem ser notado até mesmo por programadores experientes. Mas, uma vez que você chega à parte que deu errado, o problema se torna extremamente claro e simples.

O Heartbleed não é um problema com as tecnologias TLS/SSL que criptografam a internet. Não é nem mesmo um problema com a forma como o OpenSSL funciona na teoria. É apenas um erro no código.

Quando dois servidores se preparam para fazer um aperto de mão criptografado, eles realizam algo chamado de “heartbeat” (batimento cardíaco) – é nisso que se inspira o nome do bug Heartbleed (algo como “hemorragia cardíaca”).

Heartbeats são uma forma de dois computadores que conversam entre si garantirem que o outro ainda está vivo: dessa forma, se algo der errado durante o processo, ele não continua. Eles fazem isso enviando dados um para o outro, de forma constante.

O cliente (você!) envia o seu heartbeat para o servidor, e o servidor o entrega de volta. Dessa forma, se algo der errado durante a transação – por exemplo, se um computador parar de funcionar – o outro vai saber, porque os batimentos cardíacos saem de sincronia.

É um processo simples, repetido milhões de vezes por dia em todo o mundo. Mas de alguma forma, versões bugadas do OpenSSL conseguiram estragar tudo. Sean Cassidy explica tudo em bastante profundidade no seu blog.

De acordo com Sean Cassidy, o problema real, que gerou uma crise de segurança, está nesta pequena linha de código:
memcpy(bp, pl, payload);

Explicando, memcpy é um comando que copia dados, e requer três informações (parâmetros) para fazer o trabalho – são os termos dos parênteses descritos abaixo:
pl: onde estão os dados que serão enviados no heartbeat;
bp: o destino final dos dados no heartbeat;
payload: o tamanho desses dados. Basicamente, o heartbeat envia alguns dados para o servidor e ele precisa devolver para você exatamente os mesmos dados. Assim, garante-se que a conexão está segura.

No entanto, a cópia de dados é mais complicada do que parece. Quando o heartbeat vai para o servidor de destino ele não ocupa um espaço realmente vazio de memória. Sempre há alguma coisa gravada, que o computador precisa apagar para então gravar o heartbeat.

Aí está o problema: o comando memcpy pode mentir o tamanho do heartbeat. Ele pode dizer que o arquivo tem 64KB, quando ele na verdade tem 0KB. Então o servidor, confuso, vai alocar 64KB de memória – onde pode haver dados confidenciais – e enviá-los de volta para você.

É assim que hackers conseguem comprometer a segurança de sites usando o Heartbleed. Diga que vai enviar um heartbeat de 64KB, envie na verdade um arquivo de 0KB, e o servidor devolve 64KB de dados – que podem conter senhas ou endereços de e-mail, por exemplo. Repita isso diversas vezes, e você pode conseguir até chaves de criptografia.

Em termos mais técnicos: a função memcpy vai criar um espaço de 64KB (payload) no destino (bp), mas como ele recebe zero dados, esse espaço mantém tudo o que havia nele antes. Quando ele enviar os dados de volta, vai incluir tudo o que há nesse espaço. Com o Heartbleed, é possível pedir informações várias vezes a um servidor, até que ele envie de volta algo bem revelador.

O erro minúsculo recebe uma pequena correção também. Graças a Deus! Ainda bem que o mundo binário é assim SIMPLES e a correção é tão simples quanto o erro em si:
* Ler primeiro o tipo e tamanho do payload */
if (1 + 2 + 16 > s->s3->rrec.length)
return 0;
/* descartar silenciosamente */
hbtype = *p++;
n2s(p, payload);
if (1 + 2 + payload + 16 > s->s3->rrec.length)
return 0;
/* descartar silenciosamente segundo RFC 6520 seção 4 */
pl = p;

Como explica Sean Cassidy, este código tem duas funções muito simples. A primeira é checar se o heartbeat tem comprimento zero. A segunda garante que a função memcpy não está mentindo o tamanho do payload. E pronto.

Este tipo de erro é comum, e tem um nome: transbordamento de dados, ou estouro de buffer (buffer overflow). Ao escrever código, um dos erros mais comuns é “esquecer de fazer algo óbvio e verificar se os dados inseridos pelo usuário nunca estão errados”. Ainda me lembro do meu professor de C++ no ensino médio, insistindo que a gente verificasse o comprimento dos dados inseridos pelo usuário. Sempre. Só por precaução. Conta Sean Cassidy.

Felizmente, esse bug do OpenSSL é simples, e a correção é fácil de implementar, mesmo que não conserte o dano já feito. No fim, tudo se resume a esse princípio horrível e maravilhoso da computação: o computador sempre vai fazer exatamente o que você diz – nada a menos, e nada a mais. Ele é obediente, mas nem sempre é esperto – então você (ou o programador) precisa ser.
Postar um comentário

Postagens mais visitadas