Histórias do Concurso de Hacking Interno, parte I

A razão do meu sumiço de quase uma semana aqui do Blog é que estive ocupadíssimo preparando a infra para um concurso interno que estamos promovendo aqui na Tempest, como parte da nossa política de aperfeiçoamento profissional contínuo. Basicamente, a idéia é que eu desenvolvo um sistema web "mais ou menos vulnerável" e as equipes de pentest e gestão de infra-estrutura da Tempest tentam atacá-lo, ao mesmo tempo que a equipe de análise de logs tenta defendê-lo. Nesta série de posts, vou contar como é projetar e operar um concurso desses e discutir um monte de coisas que se pode aprender com eles sobre segurança de aplicações na Internet.

Projetar um concurso desses e a aplicação "vulnerável" que lhe serve como "tema" apresenta uns desafios interessantes. Primeiro, a equipe de pentest da Tempest é ao mesmo tempo muito boa e muito ruim. Explico a aparente contradição: ele são muito bons no sentido que estão afiadíssimos nas últimas técnicas e ferramentas para atacar sistemas web. E são "muito ruins" no sentido que ficaram viciados – nos últimos anos, só têm pego "adversários" relativamente fáceis: sistemas desenvolvidos por métodos, ferramentas e desenvolvedores convencionalóides, vulneráveis aos mesmos truques de sempre, muitas vezes até quase exatamente do mesmo jeito. Desenvolveram umas receitinhas de bolo e viraram mestres do "copiar-e-colar".

Não obstante, como têm tido uma taxa de sucesso de quase 100%, estão sofrendo da clássica miopia dos vencedores, creditando seu sucesso mais a si mesmos do que ao nível (ou falta dele) dos "oponentes" (no caso, os sistemas web que nossos clientes nos contratam para analisar e, indiretamente, os "arquitetos" e "engenheiros" de software que os projetaram e implementaram). Ao vencedor de uma luta desigual não se pode dar o mesmo mérito dado ao vencedor de uma luta acirrada, nem tem a mesma emoção de uma disputa cheia de reviravoltas e adversidade.

Por isso, meu primeiro desafio foi bolar um sistema web que não fosse nem tão fácil quanto eles estão acostumados, nem tão difícil que eles não conseguissem em tempo razoável. Pra mim, isso significa que eu devo ser extremamente comedido: eu passei metade da minha carreira profissional estudando contramedidas para resistir às técnicas de ataque conhecidas. Por isso, é muito fácil pra mim "errar na mão" e tornar as regras ou o sistema em si incrivelmente desfavoráveis para os atacantes.

Isso significou livrar-me de alguns vícios, também. Por exemplo, quando eu preciso criar algum novo sistema web, sempre que posso, uso autenticação HTTPS mútua por chaves públicas e privadas (AHMCPP), ao invés do batidíssimo "nome+senha". O AHMCPP é intrinsecamente resistente à maioria das vulnerabilidades e técnicas de ataque que assola os "nome+senhas". Além disso, quase a totalidade do AHMCPP já vem implementada no servidor web, diminuindo a quantidade de código que eu tenho de escrever. É mais seguro contra a maioria dos ataques clássicos e mais fácil pra implementar. Não admira que eu tenha ficado viciado. Mas, se é pra fazer esse concurso ser, pelo menos em princípio, passível de ser vencido nas duas semanas de prazo, lá fui eu ter de fazer um sistema com nome e senha.

Fazia tanto tempo que eu não desenvolvia um sistema web assim que eu tinha até esquecido como é complicado fazer um sistema com nome e senha. É preciso ter uma base de usuários e senha (no AHMCPP, não é – o próprio certificado digital já tem o nome do usuário e a senha fica só na cabeça do usuário, o servidor nem precisa saber qual ela é). É preciso ter um "trocar senha" (no AHMCPP, essa funcionalidade é implementada no navegador). É preciso ter algum mecanismo para tratar os usuários que esqueçeram a senha – ou um "lembrete de senha", o que implica em usar criptografia reversível ou nenhuma criptografia em absoluto, ou um "requerer nova senha via email". É preciso ter um sistema de rastreamento de sessão: o HTTP não vem com um por default, ao contrário do HTTPS usado no AHMCPP. Tudo isso são rodas que cada desenvolvedor precisa reinventar. E fazê-lo, fatalmente reincide nas vulnerabilidades clássicas.

Outra coisa relativamente simples que eu poderia ter feito que provavelmente ferraria as chances de sucesso dos atacantes é se eu tivesse colocado um CAPTCHA na página de login. Não que a equipe da Tempest não consiga burlar CAPTCHAs – eles conseguem, sim; a questão é em quanto tempo e o fato que conseguir arrombar a porta de entrada é só o começo da missão. Por isso, optei por usar o convencionalíssimo esquema de "bloqueio por limite de erros excedido": se o usuário errar a senha mais do que cinco vezes, a conta é bloqueada e só pode ser desbloqueada pelo operador do site.

Na figura ao lado, você pode ver (ou quase – a miniatura torna quase ilegível) uma captura da convencionalíssima tela de entrada do sistema.

Mas, voltando à questão do bloqueio por limite de tentativas erradas: eu sempre fui contra esse tipo de bloqueio porque ele é trivialmente vulnerável a ataques de negação de serviço – basta você errar cinco vezes de propósito a senha de algum usuário para causar-lhe o transtorno de ter seu acesso bloqueado. Isso é especialmente verdade quando o sistema é alvo de um ataque de força bruta (tentar milhares de combinações de nomes e senha por palpite na esperança que alguma dê certo).

Pois foi exatamente o que aconteceu – assim que eu liberei o acesso ao sistema, em poucas horas as contas de todos os usuários foram bloqueadas. Por terem optado pela violência pura ao invés de estratégia, os participantes acabaram atrapalhando a si mesmos. Na monitoração, vi várias vezes palpites de nome e senha corretos, mas que não funcionaram porque a conta já havia sido bloqueada pelas tentativas erradas anteriores. Pra mim, foi um lembrete de algo há muito esquecido: há uma boa razão pelo qual esse lance de "bloquear por limite de erros" é popular – ele faz um bom trabalho em deter malfeitores. O que eu sei é que um dos participantes até me contatou reclamando que "o povo já bloqueou tudo, não tem como prosseguir".

Na realidade, dá pra prosseguir, sim, mas, não vou contar como, pois o concurso ainda está rolando. De qualquer forma, eu já tinha imaginado que isso ia acontecer e tinha deixado pronto um robô que desbloqueia as contas dos usuários de tempos em tempos (e também troca suas senhas). Acertei em conceito, errei em escala: o robô desbloqueia a senha a cada algumas horas e os atacantes as rebloqueiam em minutos. Com essa estratégia, suas chances são muito, muito baixas.

Uma precaução importante de infra-estrutura foi o isolamento: aluguei uma máquina externa à Tempest, totalmente separada de toda nossa infra-estrutura de produção, em um provedor de hospedagem estrangeiro, para hospedar o concurso. Primeiro, não queria que nem os admins da Tempest, alguns dos quais são participantes do concurso, tivessem algum acesso, o que lhe daria uma vantagem injusta em relação aos demais. Segundo, algo pode dar errado e não queria absolutamente nenhuma interferência com os sistemas primários da Tempest.

Eu também temia problemas de velocidade ou desempenho, mas até agora não apareceram, apesar de uns picos de 150 hits por segundo (daria 13 milhões de hits por dia se fossem contínuos) e 6GB de logs crus por dia (mas que caem pra uns 500MB após compactados). Por outro lado, só há 12 atacantes e nem todos eles estão operando simultaneamente. Por isso, ainda posso ter problemas, apesar da máquina onde o sistema roda ser razoavelmente decente – é um Dual Xeon de 3GHz com 2GB de memória e 250GB de disco SATA. Mas pra mim está muito claro: no dia que eu for montar um concurso público, precisarei lembrar de implementar todos os truques de contenção de tráfego que conheço.

No próximo post, que vou escrever quando o pessoal conseguir passar da tela de entrada, vou contar pra vocês mais sobre as regras do concurso, sobre os defensores e sobre outros vários quesitos de projeto que tive de abordar durante a condução deste projeto.

Próxima parte

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.
Marco Carnut | 2010-08-23 15:17:20 | permalink | topo

Grande Enildo,

Sim, pretendo abordar esse tema várias vezes, nesse em outros contextos. É um assunto vasto e fascinante. Fique ligado!

-K.

Enildo | 2010-08-23 14:30:44 | permalink | topo

Mestre Kiko

Quando terminar esses posts do concuros, por acaso irá comentar alguma coisa sobre contençao de tráfego ?

abs