
PRNG previsível do Debian OpenSSL (CVE-2008-0166)
URL original: [http://metasploit.com/users/hdm/tools/debian-openssl/][1] ([Espelho][2])
Exploit:
Ferramenta Recomendada: [Crowbar][13] (capaz de realizar força bruta em chaves SSH)
Método de Teste: [ssh-vulnkey][14] & [dowkd.pl][15]
CVE (CVE-2008-0166):
Em 13 de maio de 2008, o projeto Debian [anunciou][5] que Luciano Bello encontrou uma vulnerabilidade interessante no pacote OpenSSL que eles distribuíam. O bug em questão foi causado pela remoção das seguintes linhas de código do md_rand.c
MD_Update(&m,buf,j);
[ .. ]
MD_Update(&m,buf,j); /* purify complains */
Essas linhas foram [removidas][6] porque faziam com que as ferramentas [Valgrind][7] e Purify produzissem avisos sobre o uso de dados não inicializados em qualquer código vinculado ao OpenSSL. Você pode ver um desses relatórios enviados à equipe do OpenSSL [aqui][8]. Remover esse código teve o efeito colateral de prejudicar o processo de semeadura (seeding) do PRNG do OpenSSL. Em vez de misturar dados aleatórios na semente inicial, o único valor "aleatório" usado era o ID do processo atual. Na plataforma Linux, o ID máximo padrão de processo é 32.768, resultando em um número muito pequeno de valores de semente usados para todas as operações do PRNG.
Todas as chaves SSL e SSH geradas em sistemas baseados em Debian (Ubuntu, Kubuntu, etc.) entre setembro de 2006 e 13 de maio de 2008 podem estar afetadas. No caso das chaves SSL, todos os certificados gerados precisarão ser recriados e enviados à Autoridade Certificadora para assinatura. Quaisquer chaves de Autoridade Certificadora geradas em um sistema baseado em Debian precisarão ser regeneradas e revogadas. Todos os administradores de sistema que permitem que usuários acessem seus servidores via SSH com autenticação por chave pública precisam auditar essas chaves para verificar se alguma delas foi criada em um sistema vulnerável. Quaisquer ferramentas que dependiam do PRNG do OpenSSL para proteger os dados que transmitiam podem estar vulneráveis a um ataque offline. Qualquer servidor SSH que use uma chave de host gerada por um sistema defeituoso está sujeito à descriptografia de tráfego, e um ataque man-in-the-middle seria invisível para os usuários. Essa falha é desagradável porque até mesmo sistemas que não usam o software Debian precisam ser auditados, caso esteja sendo usada alguma chave criada em um sistema Debian. Os projetos Debian e Ubuntu lançaram um conjunto de ferramentas para identificar chaves vulneráveis. Você pode encontrá-las listadas na seção de referências abaixo.
As listas negras publicadas pelo Debian e pelo Ubuntu demonstram exatamente como o espaço de chaves é pequeno. Ao criar uma nova chave OpenSSH, existem apenas 32.767 resultados possíveis para uma determinada arquitetura, tamanho de chave e tipo de chave. A razão é que o único dado "aleatório" usado pelo PRNG é o ID do processo. Para gerar as chaves reais que correspondem a essas listas negras, precisamos de um sistema contendo os binários corretos para a plataforma alvo e uma maneira de gerar chaves com um ID de processo específico. Para resolver o problema do ID de processo, escrevi uma [biblioteca compartilhada][9] que pode ser pré-carregada e que retorna um valor especificado pelo usuário para a chamada getpid() da libc.
O próximo passo foi construir um ambiente chroot que contivesse os binários e bibliotecas reais de um sistema vulnerável. Tirei um snapshot de um sistema Ubuntu na rede local. Você pode encontrar o ambiente chroot completo [aqui][10]. Para gerar uma chave OpenSSH com um tipo, tamanho de bits e ID de processo específicos, escrevi um script de shell que poderia ser executado dentro do ambiente chroot. Você pode encontrar esse script de shell [aqui][11]. Este script é colocado no diretório raiz do sistema de arquivos Ubuntu extraído. Para gerar uma chave, este script é chamado com a seguinte linha de comando:
# chroot ubunturoot /dokeygen.sh 1 -t dsa -b 1024 -f /tmp/dsa_1024_1
Isso gerará uma nova chave DSA OpenSSH de 1024 bits com o valor de getpid() sempre retornando o número "1". Agora temos nossa primeira chave SSH pré-gerada. Se continuarmos esse processo para todos os PIDs até 32.767 e depois repetirmos para chaves RSA de 2048 bits, teremos coberto os intervalos de chaves válidos para sistemas x86 executando a versão com bug da biblioteca OpenSSL. Com esse conjunto de chaves, podemos comprometer qualquer conta de usuário que tenha uma chave vulnerável listada no arquivo authorized_keys. Esse conjunto de chaves também é útil para descriptografar uma sessão SSH previamente capturada, se o servidor SSH estiver usando uma chave de host vulnerável. Links para os conjuntos de chaves pré-geradas para chaves DSA de 1024 bits e RSA de 2048 bits (x86) são fornecidos na seção de downloads abaixo.
O interessante sobre essas chaves é como elas estão vinculadas ao ID do processo. Como a maioria dos sistemas baseados em Debian usa valores sequenciais de ID de processo (incrementando desde a inicialização do sistema e voltando ao início conforme necessário), o ID de processo de uma determinada chave também pode indicar quanto tempo após a inicialização do sistema essa chave foi gerada. Se olharmos o inverso disso, podemos determinar quais chaves usar durante um ataque de força bruta com base no alvo que estamos atacando. Ao tentar adivinhar uma chave gerada na inicialização (como uma chave de host SSH), as chaves com valores de PID menores que 200 seriam as melhores opções para um ataque de força bruta. Ao atacar uma chave gerada pelo usuário, podemos assumir que a maioria das chaves de usuário válidas foi criada com um ID de processo maior que 500 e menor que 10.000. Essa otimização pode acelerar significativamente um ataque de força bruta em uma conta de usuário remota através do protocolo SSH.
No futuro próximo, este site será atualizado para incluir uma ferramenta de força bruta que pode ser usada para obter rapidamente acesso a qualquer conta SSH que permita autenticação por chave pública usando uma chave vulnerável. As chaves nos arquivos de dados abaixo usam a seguinte convenção de nomenclatura:
/ Algorithm / Bits / Fingerprint-ProcessID
and
/ Algorithm / Bits / Fingerprint-ProcessID.pub
Para obter o arquivo de chave privada de qualquer chave pública, você precisa conhecer a impressão digital (fingerprint) da chave. A maneira mais fácil de obter essa impressão digital é através do seguinte comando:
$ ssh-keygen -l -f targetkey.pub
2048 c6:7b:14:fa:ae:b6:89:e6:67:17:ee:04:17:b0:ec:4e targetkey.pub
Se olharmos a chave pública em um editor, também podemos inferir que o tipo de chave é RSA. Para localizar a chave privada dessa chave pública, precisamos extrair os arquivos de dados e procurar por um arquivo chamado:
rsa/2048/**c67b14faaeb689e66717ee0417b0ec4e-26670**
No exemplo acima, a impressão digital é representada em hexadecimal com os dois-pontos removidos, e o ID do processo é indicado como "26670". Se quisermos autenticar em um sistema vulnerável que usa essa chave pública para autenticação, executaríamos o seguinte comando:
$ ssh -i rsa/2048/c67b14faaeb689e66717ee0417b0ec4e-26670 root@targetmachine
P: Quanto tempo levou para gerar essas chaves?