Os Problemas com o Problema das Senhas

Não, eu não errei ao digitar o título deste post. O Problema com as Senhas é um post no dicas-l que me foi recomendado hoje por um amigo que está sendo beta-tester de um treinamento online em Programação Defensiva que estamos desenvolvendo (mais sobre isso em breve). É um ótimo exemplo de uma generalização tão grosseira que chega a ponto de perder o sentido; e me dá um bom pretexto para discorrer sobre algumas questões de segurança ao redor das senhas.

Antes de mais nada, que fique claro: não tenho nada contra a "dicas-l"; muito pelo contrário: a ideia de dar uma dica curtinha por dia me parece genial – muita gente aprendeu muito sobre um monte de coisa lendo o dicas-l. Por isso, não tenho nada senão profundo respeito e admiração pelo trabalho do Rubens Queiroz, que fundou e opera a lista (e o site associado) há mais de uma década.

Aliás, o artigo nem é dele. Trata-se de uma tradução desse mini-artigo que apareceu na revista Business Week há quase três meses atrás. Para a conveniência do leitor, reproduzo aqui o texto (o rodapé do site informa que o material lá veiculado é licenciado pela licença "atribuição+não-comercial+recíproca" do Creative Commons, que me garante que eu posso fazer isso sem medo de ser processado):

Há tanta coisa obtusa nessa tabela que eu tenho dificuldade até de decidir por onde começar, mas vamos lá: primeiro, o próprio termo "quebrar uma senha" não é muito claro, nem muito bem definido. A versão original em inglês diz outra coisa: "randomly guess you password" (acertar sua senha por acaso), o que também não é muito preciso.

Na realidade, o que ele parece querer dizer é que esses seriam os tempos estimados quando se usa uma técnica chamada "busca exaustiva". Nela, um programa de computador fica testando todas as possibilidades dentre um certo "universo". A quantidade de possibilidades depende da definição do "universo": o universo de todas as possíveis palavras compostas de seis letras maiúsculas é 26 (todas as letras do alfabeto) elevado à sexta potência (pois há seis letras), totalizando 308.915.776 possíveis senhas. Nenhum ser humano tem paciência de testar essa quantidade de senhas, mas os computadores têm.

Acontece que existem várias outras técnicas para se descobrir as senhas dos usuários além da busca exaustiva. Falarei delas mais adiante; por enquanto, vamos seguir a premissa do artigo e nos focamos somente na busca exaustiva.

Seguindo essa linha, outra esquisitice salta aos olhos: do jeito que a tabela está, dá a falsa impressão de que senhas com letras maiúsculas são mais resistentes do que as em minúsculas, pois os números na coluna "maiúsculas" são sempre maiores do que os na coluna "minúsculas". Pela mesma lógica, dá a impressão de que senhas compostas de números e símbolos são mais fortes do que as anteriores. Na realidade, senhas compostas apenas de letras maiúsculas são exatamente tão resistentes quanto senhas compostas exclusivamente de letras minúsculas, pois a quantidade de letras maiúsculas e minúsculas é exatamente a mesma: 26 letras.

Essa aberração não existe na versão original do artigo – ele está em forma de lista e cada item é precedido de um sinal de mais, sugerindo o que realmente se quer dizer: que senhas compostas de seis letras minúsculas levam tal tempo, e que se acrescermos letras maiúsculas (além das minúsculas, totalizando 52 caracteres, ao invés de apenas 26) então o tempo vai ser bem maior, e que se acrescermos a possibilidade de usarmos números e símbolos, o tempo vai ser maior ainda. A falta dos "sinais de mais" aqui faz toda a diferença e, ao meu ver, o tradutor pecou ao omiti-los, removendo o caráter "cumulativo" da versão original que é essencial à corretude técnica.

Dividindo as 308.915.776 possíveis senhas por 10 minutos, obtém-se uma velocidade de 514.860 senhas por segundo. Repetindo essa conta para os outros itens da tabela, o resultado gira mais ou menos em torno disso, às vezes um pouco pra mais, às vezes um pouco pra menos, provavelmente porque o autor original arredondou os valores finais para horas, dias, meses e anos inteiros (ao passo que o resultado exato teria ficado fracional).

Testar cerca de 500.000 senhas por segundo é uma velocidade típica do que se chama "busca exaustiva offline" – ela acontece quando o atacante já obteve acesso a um banco de dados, mas ele está cifrado. Bons sistemas de cifragem de senha não podem ser atacados diretamente; ao invés, o atacante é forçado a ficar testando para ver qual dá certo.

Existe também o ataque de "busca exaustiva online": nesse cenário, o atacante não teve acesso ao banco de dados; ele tem apenas acesso à tela de login, onde se pede o nome do usuário e a senha. Nesse tipo de ataque, é raro se conseguir velocidade maior do que algumas centenas de tentativas por segundo (de sorte que os números na tabela acima teriam de ser muito maiores).

Muitos sistemas também limitam a quantidade de tentativas que um determinado usuário pode fazer: por exemplo, se um mesmo usuário (ou atacante tentando fazer busca exaustiva) errar a senha mais de três vezes, a conta do usuário é bloqueada. Muitos projetistas de sistemas de segurança acham isso muito seguro, mas na realidade apenas troca uma vulnerabilidade por outra: o sistema passa a ser vulnerável a "negação de serviço direcionada" – se eu souber (ou tiver como descobrir) o seu nome de usuário, eu vou lá e erro a senha de propósito três vezes para bloquear seu usuário, o que te força a ter de pedir pro administrador desbloqueá-la manualmente.

O artigo está certo em dizer que um dos grandes custos de operar sistemas baseados em senhas é justamente esse lance de você ter de vez em quando que pedir pro gestor do sistema desbloqueá-la ou recadastrá-la. Se cada incidente custa dez dólares, isso eu já não ponho muita fé; depende da maneira exata como o processo é feito. Mas que é um custo significativo e uma aporrinhação, isso é.

O artigo diz que 50% dos usuários usa senhas "simples", baseadas em palavras comuns. Eu não insisto muito no 50% – já vi lugares em que medimos 18%, já vi outros em que medimos 98% (sério!). Mas que nomes de parentes, namorado(as), marido/esposa, filhos, bichos de estimação, lugares, números simples ("123456", "111111", entre outros), datas de nascimento, placas de carro e números de telefone são os mais comuns, realmente são.

Daí a existência do chamado "ataque de força bruta por dicionário". (Chama-se de "ataque de força bruta" tudo que tem a ver com tentativa-e-erro repetitiva; a própria "busca exaustiva" é um caso particular e extremo de uma "força bruta".)

A ideia do dicionário é a seguinte: cria-se um dicionário com as palavras que os usuários mais frequentemente escolhem e vamos tentá-las uma por uma. Por exemplo, aqui você pode baixar um dos vários dicionários que usamos – ele tem pouco mais de 600.000 palavras. Eis a vantagem de usá-lo: ele tem muito menos itens do que as 308.915.776 palavras de seis caracteres. Com ele, o sucesso não é garantido, mas o resultado sai muito mais rápido.

Eu já usei esse dicionário várias vezes e a taxa de sucesso histórica dele (ou seja, não é uma estimativa; é um número que eu medi ao longo de vários ensaios de força bruta que fiz ao longo dos anos) gira em torno de 7 a 23% dos usuários – o que mostra perfeitamente bem como as pessoas tendem a ser repetitivas e pouco imaginativas na hora de escolher senhas.

Mas esses são apenas alguns dos problemas que as senhas têm. Existem vários outros. Entre eles:

  • Aqui na Tempest a gente já passou por diversos casos onde esses ataques de 'busca exaustiva' e 'força bruta' nem sequer foram necessários: uma quantidade surpreendente de sistemas web que já auditamos guarda as senhas às claras, sem cifragem nenhuma. Nesse caso, se o atacante obtém acesso ao cadastro dos usuários, obtemos todas senhas "de bandeja", sem esforço adicional nenhum.

  • Todo sistema e/ou banco de dados tem um "administrador" que, no âmbito daquele sistema, tem poder absoluto e pode ver ou descobrir as senhas de qualquer usuário. Então, é preciso assumir que se você sabe sua senha, alguns dos operadores lá do seu site ou sistema também sabem (ou podem descobrir quando quiserem, e quase sempre sem deixar rastros).

  • Além disso, já houve vários casos de bancos de dados de senhas que vazaram. Se você tiver algum cliente BitTorrent, experimente baixar este torrent com centenas de milhares de senhas que vazaram do Gawker.com.

  • O certo seria você usar diferentes senhas em diferentes sistemas e trocá-las regularmente. Mas com tantos serviços online, ninguém consegue decorar tantas senhas diferentes. O resultado inevitável é que você acaba usando a mesma senha em diferentes sites ou sistemas. Isso também significa que se alguém descobrir sua senha em um deles, descobre em todos eles.

  • Uma consequência do item anterior é que você está sempre implicitamente confiando que os administradores de um sistema (digamos, seu site de rede social) não pegam sua senha e a usa (ou vaza para alguém usar) para "invadir" sua conta em outro site.

  • Um dos lugares mais fáceis de pegar sua senha é no teclado, quando você a digita. Uma das fraudes bancárias mais populares no início do século XXI era colocar câmeras escondidas filmando os teclados e a tela dos caixas eletrônicos. É por isso que os bancos inventaram códigos adicionais (as "letrinhas", em alguns bancos) ou aquele lance de mudar a posição dos números e as teclas que você aperta. Essa simples medida já fez com que muita gente menos instruída simplesmente deixasse de usar os caixas eletrônicos, aumentando as filas nos bancos.

  • Outra maneira popular para pegar as senhas direto a partir do teclado são os chamados keyloggers (tradução idiomática livre minha: "gravadores de teclas"). Há dois grandes tipos deles: os "em hardware", como esses aqui vendidos na ThinkGeek. Há também "keyloggers em software", que normalmente são programinhas embutidos dentro de vírus e que transmitem o que você digite em tempo real para os malfeitores.

  • Senhas requerem toda uma "infra-estrutura adicional": os "lembretes de senha", "esqueci minha senha", CAPTCHAs para coibir ataques de força bruta online, etc. Isso custa tempo extra dos desenvolvedores, precisa ser monitorado e operado e geram outras vulnerabilidades. Por exemplo: em trabalhos de Ethical Hacking, várias vezes nós conseguimos chutar corretamente a senha do usuário baseado na pista contida no "lembrete de senha" (eu lembro de umas duas ou três vezes que o lembrete de senha era a própria senha!).

Diante de tantos problemas, é fácil ficar com a sensação de que está tudo perdido e que "a coisa não tem jeito", "é assim mesmo e não tem como melhorar". Não é bem assim; as coisas têm jeito, sim. Em um futuro artigo, vou explicar como eu gerencio as diversas senhas que eu tenho; também vou falar sobre várias tecnologias (infelizmente pouco adotadas) que podem dar fim, pelo menos diminuir drasticamente, a quantidade de senhas que temos de lembrar, ao mesmo tempo que amenizam (e em certos casos até eliminam) os diversos problemas que mencionei acima.

Eu sei que o artigo original e a versão na dicas-l pretendiam ser apenas vagamente ilustrativos e tinham de ser curtinhos. Mas, ao colocar a questão na forma de uma conta imprecisa, sem explicitar exatamente o que os números significam, e salpicando factóides fora de contexto e com um foco enviesado, o artigo acaba perpetuando exatamente as confusões que pretendia desfazer. Pra mim, a didática não pode nem precisa sacrificar a corretude.

Como eu não gosto de escrever artigos que só reclamam e não oferecem soluções, eis aí minha sugestão para o que seria uma ilustração mais clara e tecnicamente precisa do ataque de busca exaustiva para o caso de seis caracteres:

Está incompleto, eu sei; eu deveria ter feito os casos com 7, 8 e 9 caracteres. Quando der, eu faço. Mas acho que deu para pegar a idéia. Note que eu digo explicitamente que se trata de um ataque de busca exaustiva. Na minha experiência, nada como enumerar algumas das possibilidades para deixar as coisas mais concretas na cabeça do leitor. Note o subtítulo explicando a "conclusão". Enfim, acho que deu para pegar a idéia.

Ser didático e tecnicamente preciso dá trabalho, eu sei. De fato, levei quase uma hora pra fazer essa figurinha. Mas quando esclarece, vale muito a pena.

Enfim, há certas questões que intrinsecamente não se prestam a abordagens simplistas – e, como tentei demonstrar, "o problema das senhas" certamente é uma delas. Como qualquer coisa na fronteira entre as questões técnicas e as capacidades cognitivas humanas, acaba se revelando uma questão muito mais profunda do que aparenta à primeira vista. Mas é difícil negar que o problema das senhas é que as senhas têm problemas demais.

Comentários
Aceita-se formatação à la TWiki. HTML e scripts são filtrados. Máximo 15KiB.

 
Enviando... por favor aguarde...
Comentário enviado com suceso -- obrigado.
Ele aparecerá quando os moderadores o aprovarem.
Houve uma falha no envio do formulário!
Deixei uma nota para os admins verificarem o problema.
Perdoe-nos o transtorno. Por favor tente novamente mais tarde.
Bruno Drago | 2011-06-18 21:12:24 | permalink | topo

Muito bom o artigo Kiko :D

Abs Bruno

Ricardo Ulisses | 2011-04-16 15:09:43 | permalink | topo

Kiko,

Belo artigo! É sempre bom podermos contar com o rigor matemático e a prosa didática que lhes são tão peculiares.

Ricardo.

Marco Carnut | 2011-04-12 18:02:08 | permalink | topo

Oi Marcelo,

Pois é – tendo-se o dicionário certo para "chegar perto", a força bruta fica muito menos bruta. No seu caso, você provavelmente tinha alguma idéia de "por onde ia" a senha correta e a força bruta foi só para "acertar os detalhes", não foi? Suspeito que sim, pois 18 min * 60 * 2/segundo = 2160 tentativas, que é bem pouco nesse tipo de ensaio.

Fico feliz que você tenha gostado do artigo. Eu mesmo passo por isso que você diz quase todo dia: alguém lê uma coisa mal escrita em alguma revista popular e lá vou eu ter de desatar o nó na cabeça do cara. Resolvi escrever pra poder reaproveitar. :)

-K.

Marcelo Caiado | 2011-04-12 14:38:02 | permalink | topo

Ótimo o artigo!

Eu havia lido o artigo da BusinessWeek (em Português) e fiquei impressionado com o amadorismo do conteúdo do artigo. Aliás, esse tipo de matéria só atrapalha o trabalho do profissional de segurança, que precisa esclarecer que não é nada daquilo que foi escrito (no estilo CSI...), e o seu artigo ajuda bastante a prestar esse esclarecimento.

Como exemplo, no ano passado eu "quebrei" uma senha do TrueCrypt em 18 minutos, a qual possuía 9 caracteres (maiúsculas, minúsculas e números). Usei um script Perl, que, por força bruta, testava 2 palavras por segundo (sabemos que 1 milhão de senhas por segundo não é fora da realidade com diversos programas publicamente disponíveis, com os da ElcomSoft), juntamente com um dicionário personalizado para o caso, e executando em um laptop de baixa performance.

Joao Lins | 2011-04-08 12:51:55 | permalink | topo

Kiko,

Gostei do artigo porque ele mostra alguns pontos importantes que devem ser levados em consideração antes de se implementar um bom sistema de autenticação.

Acredito que o seu amigo estava procurando algo como a complexidade da senha que ele deveria usar para um sistema e deu de cara com um artigo que deixa a desejar na parte conceitual, além de mostrar apenas um viés dos ataques e ainda assim de forma implícita.

Quanto a testar 500.000 senhas por segundo acho que é um numero baixo. Aqui na Tempest, para ataques offline a hashes MD5 e SHA1, já conseguimos desenvolver algoritmos que chegam a fazer 4.000.000 testes por segundo usando a ideia de Rainbow Tables.

Pelo que você escreveu acho que teremos um artigo interessante sobre autenticação utilizando certificados digitais.

[]'s