Entendendo o bug Heartbleed. 

Heartbleed é o nome dado a falha encontrada no OpenSSL, implementação aberta do SSL/TSL, protocolo que permite a comunicação entre servidor-cliente através de um canal criptografado. A falha incide sobre as versões 1.0.1 até 1.0.1f.

O problema ocorre porque o servidor rodando a versão afetada do OpenSSL não verifica o tamanho dos dados recebidos durante o Heartbleed.

É basicamente assim, para garantir a conexão o cliente envia uma sequência de dados, o servidor recebe, reserva um espaço de até 64kb para salva-los e posteriormente os devolve. Essa solicitação é chamada de Heartbleed.

Como não há a verificação do comprimento dos bytes enviados durante o processo, torna-se possível submeter sequências de dados inferiores as declaradas para receber blocos de memória com “bytes extras”, muitas vezes abrigando informações privilegiadas.

Isto é possível porque as áreas da memória do computador, mesmo quando não utilizadas, costumam guardar vestígios de programas e informações recém-processadas. Como o código do OpenSSL apenas reserva o espaço e não zera os blocos, acaba enviando toda a “sujeira” contida nesses locais para o cliente.

Olha o descuido:

memcpy(bp, pl, payload);

memcpy() : Copia os dados de pl para bp;

@pl      : Dados recebidos pelo servidor;
@bp      : Dados que serão remetidos ao cliente;
@payload : Quantidade de bytes copiados; submetido pelo cliente

Os programadores não procederam com nenhuma verificação de dados antes da utilização da função memcpy().

A técnica utilizada para explorar a falha é conhecida como pescaria.
Essa é uma ilustração simples de um bloco alocado estaticamente recheado de “lixo”:

#include <stdio.h>

#define SIZE 65535

int main ()
{
	char buffer[SIZE];
	int i;

	for(i = 0; i <= SIZE; i++)
		printf("%c", buffer[i]);

	return 0;
}

Desviando a saída para o hexdump é possível deixar as informações mais claras:

$ ./pescando | hexdump -e "80 \"%_p\" \"\\n\""

Observe um dos trechos abaixo:

vF0....`.e.<...@fF0......d.<...hfF0......e.<.....Q.......a.<.............d.<...
..........................e.<.....F0............x...<.....a.<...........X.e.<...
.eF0.....fF0..............a.<.............'.<...................8...<.....a.<...
..........f.<....eF0............(...<.....a.<....vF0.....gV.<....|..<....pj.<...
?........){..... ...0...........X...............?............... ...........<...
....<....................|......@........vF0.....gV.<....vF0....`...<...........
 vV.<...?................|..<....vF0.....vF0................<... vV.<....50.<...
/home/fernando/pescando.....<...............<....gF0......`..`....v...y.X...<...
..i.<.....a.<.......e.....i.<....eF0................<.....a.<.............i.<...
PgF0................<.....a.<.............i.<....gF0................<.....a.<...
..j.<.....i.<.....i.<....4j.<.....i.<.......<....pj.<....................Wk.<...
PiF0.........`....v...y.....<............^k.<...PiF0.........`....v...y.....<...
.........Yk.<...PiF0......@..`....v...y.............5...-.......................
............<... .i.<.....a.<...........(.i.<....gF0................<.....a.<...
........@.i.<....hF0................<.....a.<...@.i.<....4j.<...(.i.<.......<...
.pj.<.......<...........O.F0....@.F0............................................
................................................................................
*
................/proc/10811/exe.................................................
................................................................................
*
........................................................M.b.<...............<...
........B.a.<...........M.b.<............'#.<...........B.a.<...........M.b.<...

Fazendo uma filtragem parcial com o programa strings.

$ ./pescando | strings
ogg.so.0
attr.so.1
h10827
/home/fernando/pescando
/proc/10827/exe

Pesquei! Nada esclarecedor, confesso. Mas imagine um servidor carregado de dados, processando centenas de milhares de bytes todos os dias.

Anúncios