O Gerador de Números Aleatórios Previsíveis no OpenSSL do Debian
Rec 17-mai-2008 14:08
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 2
x possíveis números. Vamos
calcular isso para alguns valores:
- Se você pede um número aleatório de 32 bits, ele lhe dará um dentro quatro bilhões de possíveis números (232 = 4.294.967.296);
- Se você pedir um número de 64 bits, ele será escolhido de um conjunto de 18 quintilhões de números (264 = 18.446.744.073.709.551.616). É uma quantidade tão grande de possibilidades que a maioria das pessoas tem até dificuldade de imaginar. Ouvimos o tempo todo falar de milhões de reais, de vez em quando em bilhões e raramente em trihões, mas "quintilhões" é uma quantidade tão grande que raramente ouvimos falar.
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 afetaco -- 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
or
~/.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:
- Instale a versão mais recente do pacote SSH. No Debian, faça assim: primeiro, dê um
apt-get update
para obter as novas listas de pacotes. Então, dê um apt-get install openssh-client openssh-server openssh-blacklist
. O processo de atualização checará se as chaves do seu servidor estão vulneráveis e, se for o caso, oferecerá para regerá-las. Se não forem vulneráveis, elas serão mantidas intactas. Isso resolve a parte "servidor" do problema.
- Rode o utilitários
ssh-vulnkey
que vem com a nova versão das ferramentas SSH. Ele checará se as chaves no seu diretório ~/.ssh
é uma das vulneráveis. Se ele disser "COMPROMISED", gere um novo conjunto de chaves com o utilitário ssh-keygen
(leia a página de manual para detalhes.) Em seguida, copie essas novas chaves para todos os ~/.ssh/authorized_keys
em todos os servidores para os quais você anteriormente havia copiado as chaves vulneráveis. Esse é a parte difícil -- pode ser que você nem sequer se lembre mais de todos os computadores para os quais copiou suas chaves; ou alguns deles podem estar indisponíveis no momento e você não lembrar de fazer isso depois. E se você tiver chaves vulneráveis em centenas de servidores, vai ser uma trabalheira.
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 sporte 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.
topo