http://www.pedro.jmrezende.com.br/sd.htm > Algoritmos: SSH NumGen

O Gerador de Números Aleatórios Previsíveis no OpenSSL do Debian


Marcos Carnut *
Tempest Technologies
Recife, Brasil
19 de Maio 2008

[Oringinal post ]



A essa altura você provavelmente já ouviu isso de algum outro lugar, mas aqui vai minha abordagem à questão: vários programas cruciais que usam serviços de criptografia de chaves públicas providos por certas versões da biblioteca OpenSSL provida por distribuições de Linux derivadas do Debian (inclusive as populares Ubuntu e Kubuntu) contêm uma grave vulnerabilidade que pode tornar suas máquinas passíveis de invasão. A extensão exata de como o problema lhe afeta depende de como exatamente as coisas estão montadas no seu computador, como explicarei adiante.

A raiz do problema é a seguinte: há quase dois anos atrás, um dos mantenedores do pacote OpenSSL do Debian desativou algumas linhas de código do gerador de números aleatórios. A motivação por trás da mudança parece ter sido porque quando se passava aquele código pelo Valgrind, um dentre vários programas de diagnóstico de problemas comuns em código fonte, ele reclamava de um possível uso de dados não inicializados.

A segurança de quase todos os programas baseados em criptografia depende deles escolherem chaves que são imprevisíveis para um atacante. Normalmente, quando você pede às rotinas do OpenSSL para gerarem um número aleatório de x-bits, ele é sorteado de um conjunto de 2x possíveis números. Vamos calcular isso para alguns valores:

Ao escolhermos chaves para sistemas de criptografia de chaves públicas, precisamos de alguns números aleatórios da ordem de 100 dígitos decimais. O tamanho do conjunto de possibilidades de onde esse número vem é tão grande que muita gente não sabe nem o nome dele, mas ele tem um nome: chama-se "dez duotrigintilhões", também conhecido como "um googol".

Mas o que isso tudo significa é que a chance de alguém de fora acertar o número correto que compõe nossas chaves é praticamente zero porque nossa chave é apenas uma perdida dentre todos esses duotrigintilhões. Tentar cada uma delas não é viável precisamente por essa razão: é coisa demais. Em outras palavras, a segurança da sua chave advém do fato de ela ser indistringuível do resto da multidão de possíveis chaves.

O trecho de código que o mantenedor do Debian alterou, contudo, fez com que o OpenSSL passasse a tirar os números aleatórios a partir de um conjunto de apenas 32.768 números. De repente a multidão se tornou MUITO menor, tão pequena que se tornou perfeitamente viável listar cada membro individualmente.

A maior parter dos usuários do Windos provavelmente nunca ouviu falar do SSH, mas a maioria dos usuários de Linux que vão além das interfaces gráficas o usam todo santo dia -- eu, inclusive. Para o benefício dos meus muitos leitores Windows-cêntricos: o SSH é um programa de controle remoto que permite às pessoas controlar seus computadores à distância via Internet, um pouco como o "Remote Desktop" do Windows, mas (normalmente) muito mais seguro. Para saber mais, veja o artigo em Inglês sobre ele na Wikipedia (o em Português é, infelizmente, muito fraquinho e fora de foco).

O SSH usa criptografia de chaves públicas para duas coisas: autenticar servidores e, opcionalmente, autenticar usuários. Mas se você gerar novas chaves (o que acontece automaticamente quando o servidor é instalado pela primeira vez ou ao ser atualizado) com a versão vulnerável do software, a chave quase certamente estará contida nesta lista (ou nesta).

Isso significa que um terceiro pode armar o que a turma de criptografia chama de "ataque "man-in-the-middle"": primeiro, ele pede ao seu servidor SSH que forneça suas chaves públicas (negá-las impediria usuários legítimos de conectar). Depois ele usa a lista para ver que chaves públicas correspondem a que chaves privadas (essa é a parte que não dá certo quando o gerador de números aleatórios é bom). Daí ele pode instalar um servidor SSH que se identifica exatamente como o seu. Se o atacante também puder te redirectionar para esse servidor impostor (relativamente fácil), você pode ser ludibriado a conectar nele -- onde estará à mercê do atacante. Se ele for bastante caprichoso, você pode não notar a diferença antes de já ter digitado alguma senha importante ou dado ao atacante acesso a onde ele não deveria ter. Se o atacante for bem caprichoso mesmo, você pode nem notar em absoluto.

Para autenticar usuários, o SSH provê vários métodos de autenticação. Pode-se usar o antigo método de "nome de login+senha", mas muita gente, inclusive eu, adota o método mais moderno baseado em "chaves públicas", porque normalmente é mais seguro e provê uma série de vantagens práticas: por exemplo, você pode me dar acesso a um servidor seu somente copiando minha chave pública pra lá -- não haveria necessidade de eu criar mais uma senha no seu servidor; isso tamém torna possível eu ter uma única senha para acessar remotamente vários servidores, ainda que nenhum deles saiba que senha é essa.

Todavia, se a chave que eu uso para me identificar tiver sido gerada com a versão vulnerável do SSH do Debian, minha chave seguramente estaria numa daquelas listas que citei acima -- o que significa que um atacante poderia facilmente saber qual a chave privada correspondente. A menos que algo o detenha, o atacante poderá ter acesso aos mesmos servidores que eu, pois poderá usar exatamente a mesma identificação que eu.

Note que a vulnerabilidade é no processo de geração de chaves. Isso explica porque eu mesmo não fui muito afetado -- minhas chaves SSH foram geradas em 1999, usando uma versão do programa SSH que não tinha esse problema com os geradores de números aleatórios. Se suas chaves pessoais (aquelas nos arquivos ~/.ssh/id_dsa ou ~/.ssh/id_rsa) não estão na lista das chaves comprometidas, então você não está no grupo de alto risco.

Para verificar se suas chave estão afetadas, faça o seguinte:

O novo servidor SSH rejeita conexões de usuários usando chaves na "lista negra", de sorte que se seu sistema ainda tiver usuários com chaves vulneráveis, eles não mais conseguirão conectar. Menos mal, mas um potencial transtorno.

Por outro lado, o cliente SSH não evita que você conecte em servidores usando chaves na lista negra. Isso é um tanto infeliz, porque você não tem uma maneira simples de determinar se você está conectando ao servidor correto ou para uma armadilha "man-in-the-midde". Mas é compreensível porque os desenvolvedores do OpenSSH fizeram isso: em muitos casos, o SSH é a única maneira que as pessoas têm de conectar aos seus servidores. Se o cliente SSH não te deixasse chegar lá, você poderia ficar sem nenhum meio de consertar o problema. Mas você realmente deve evitar conectar a servidores cujas chaves estão na lista negra a menos que você tenha outros meios de ter certeza estar conectando ao servidor correto.

Se sua versão das ferramentsa SSH já tiver o utilitário ssh-vulnkey, você pode testar remotamente se um servidor tem chaves vulneráveis:

ssh-keyscan -t dsa,rsa your-server-name-or-ip-address | cut -d' '  -f2- | ssh-vulnkey -

(A página de manual do utilitário "ssh-vulnkey" tem uma receita semelhante, mas que não funciona; a saída do utilitário ssh-keyscan tem um campo a mais com o nome do servidor, que o ssh-vulnkey não entende e o faz abortar silenciosamente. Essa é a razão do comando cut no meio da cadeia acima.)

O problema pode ser mais profundo ainda: uma coisa que eu não vi muita gente comentando é o impacto disso tudo nas chaves simétricas usadas para cifrar o grosso dos dados em trânsito. Se houver apenas 32,768 chaves simétricas, também ficaria trivialmente fácil decifrar dados em trânsito (é por essas e outras que as agências de inteligência gravam tudo, mesmo que não consigam decifrar hoje: pode muito bem ser que eles consigam decifrar no futuro.) A triste conclusão será que durante quase dois anos, o SSH do Debian era quase tão inseguro quanto o TELNET.

Essa confusão trouxe novo combustível a uma antiga guerra: o fato que os mantenedores do Debian fazem mudanças próprias em muitos pacotes. No geral, eu acho que isso é uma boa coisa: mantém a plataforma estável e genericamente funcionando. Por exemplo, um kernel 2.6.18 personalizado meu recentemente falhou em um novo servidor porque ele não tinha suporte ao chipset SATA ICH9 da Intel, ao passo que a versão 2.6.18 do Debian funcionou perfeitamente porque os mantenedores portaram esse recurso de kernels mais novos. Isso me ajudou muito a consertar o problema, por o servidor pra funcionar rápido e eventualmente consertar meu kernel personalizado.

Nesse incidente, porém, o que aconteceu é que alguém mexeu em um código crítico de segurança sem se dar conta das implicações. Eu não gostaria de estar na pele desse cara; sem dúvida, muitas pragas devem estar sendo invocadas na direção dele. E ainda dá o Debian uma má publicidade que não creio que ele mereça, além das piadinhas de sempre. Ressucitaram até uma antiga tirinha do Dilbert.

Minha sugestão para o pessoal do Debian é que apenas certas pessoas com a competência certa mexam em código de segurança crítico. Mas, claro, é mais fácil falar do que fazer. O mero ato de definir o que é "crítico para a segurança" já é um trabalhão -- muita coisa que não parece ser relacionada à segurança, na realidade é ("Aaah! Eu não sabia que um gerador de números aleatórios era uma coisa crítica para a segurança!"). Sem falar em angariar gente com a competência certa.





* O Author

Marcos Carnut é um consultor de segurança da informação vivendo em Recife. Seus interesses técnicos giram em torno de segurança de redes de computadores e da informação, firewalls, sistemas de detecção de intrusão, análise de logs, criptografia e infra-estruturas de chaves pública. http://www.postcogito.org/

.

Copyright
by Marcos Carnut, 2008
Esse artigo é aqui publicado sob a licença em http://creativecommons.org/licenses/by-nc-sa/2.5/deed.pt