Análise de Causa Raiz de Vulnerabilidades no SDL

**

"You should LOVE your security bugs!" -

Dr. Herbert Thompson na RSA Conference 2006

Segundo todas as estatísticas, voar é a forma mais segura de transporte. Todos sabemos que complexidade é a maior inimiga da segurança, e por isso chega a ser difícil acreditar que um meio de transporte complexo como um avião seja mais seguro do que ir tranquilamente por terra, mas os dados são incontestáveis (se existisse um "GNU/carro" os seus fanboys certamente contestariam assim mesmo). Isso não é resultado de um milagre, mas sim da obsessão quase fanática da indústria aeronáutica em entender as causas que levaram a cada acidente. Todos os acidentes são investigados, e dessas investigações surgem as medidas que vão impedir que novos acidentes ocorram.

Reconstrução dos destroços do vôo TWA 800

(Como exemplo de casos onde a indústria aeronáutica levou essa obsessão ao extremo, veja esta apresentação sobre a investigação dos acidentes do De Havilland Comet, o primeiro avião de linha comercial a jato. Ou a investigação do acidente do vôo TWA 800 em Long Island, um trabalho excepcional de resgate e remontagem de destroços que provavelmente salvou a vida de muitas pessoas que voam hoje em Boeings 747).

Assim como o objetivo da indústria aeronáutica é um vôo sem acidentes, o objetivo final de um processo de desenvolvimento seguro é produzir um software sem vulnerabilidades de segurança. Qualquer vulnerabilidade que seja encontrada é portanto um sinal que esse processo falhou em algum ponto. Pode ser que o treinamento que você deu aos seus desenvolvedores não tenha coberto aquela vulnerabilidade. Pode ser que as suas ferramentas estejam deficientes. Pode ser que o seu checklist de revisão esteja incompleto.

Os bugs de segurança são então a melhor fonte de feedback para a melhoria do seu processo de desenvolvimento (esse é o sentido da frase acima do dr. "Hugh" Thompson). Eles são de certa forma puro ouro como material de aprendizado e otimização, a característica que define um processo maduro. A otimização do processo só acontece se for feita uma análise de causa raiz de cada vulnerabilidade, e se os resultados desta análise forem incorporados em uma nova versão do processo.

Na Microsoft todas as vulnerabilidades encontradas são submetidas a uma análise de causa raiz. Todas. Na verdade o nosso time de segurança analisa até vulnerabilidades em softwares de terceiros (por isso Michael Howard é um dos poucos funcionários da empresa que tem permissão para ler código GPL), apesar de isso não ser feito de forma sistemática. A análise de causa raiz é a melhor fonte de feedback para a melhoria e otimizaçao do Processo de Desenvolvimento Seguro (SDL) da Microsoft, e sem ela o processo jamais teria evoluído.

Um exemplo desse tipo de análise foi postado no blog do SDL pelo próprio Michael Howard. É o resumo da análise da vulnerabilidade na interface de administração do serviço DNS, corrigida no boletim MS07-029. Abaixo estão os principais pontos da análise:

¦ Os produtos afetados

Como a vulnerabilidade do MS07-029 se encontra no servidor DNS, somente as versões de servidor do Windows (Windows 2000 Server, Windows 2003) são afetados. A vulnerabilidade não é encontrada no Windows 2000 Professional, XP ou Vista.

¦ A natureza da vulnerabilidade

Trata-se de um estouro de buffer na pilha de execução, em uma interface RPC com acesso anônimo. Isso faz com que o bug seja classificado como crítico.

¦ O código afetado

A vulnerabilidade afeta a seguinte estrutura::

typedef struct _CountName {

    UCHAR Length;

    UCHAR LabelCount;

    CHAR RawName[ DNS_MAX_NAME_LENGTH+1 ];

} COUNT_NAME, *PCOUNT_NAME;

Esta estrutura é alocada na pilha ao ser passada como parâmetro para a função Name_ConvertFileNameToCountName. Esta função também recebe como parâmetro o nome do servidor DNS que vai ser convertido, e o estouro de buffer acontece quando este nome é copiado para RawName dentro da estrutura. A cópia é feita sem checagem de limites e o buffer estoura. O post no blog SDL mostra o código da função onde

¦ Onde o processo falhou

Assim como um acidente aéreo, uma vulnerabilidade de segurança é sempre o resultado de um conjunto de falhas técnicas e de processo, e nunca de uma única falha. No caso do MS07-029 essas foram as falhas que permitiram que a vulnerabilidade existisse:

1. A falha fundamental foi o time de desenvolvimento achar que o acesso a esta interface RPC era restrito aos administradores, quando na verdade ela também permitia acesso anônimo. Isso faz uma diferença enorme em termos de superfície de ataque, na avaliação dos riscos e na priorização dos testes de segurança, como testes de fuzzing.

2. O time de desenvolvimento não tinha uma ferramenta para validar se uma determinada interface realmente só era acessível pelo administrador.

3. As ferramentas de análise estática de código não detectavam vulnerabilidades de estouro de buffer em arrays de tamanho fixo sendo passadas como parâmetro de função, como é o caso aqui.

4. Como se supunha que a interface fosse somente acessível como administrador, os testes de fuzzing neste ponto de entrada foram mínimos. O servidor DNS é intensamente testado via fuzzing na portas TCP e UDP 53, que tem uma enorme superfície de ataque (ponto de entrada de acesso anônimo, protocolo complexo, acessível através de firewalls, etc.), mas o mesmo escrutínio não foi dado na interface de administração RPC.

5. O Windows 2000 Server não tem nenhum tipo de defesa contra execução de código remoto em estouros de buffer, como /GS, DEP e ASLR. O Windows Server 2003 é compilado com /GS e suporta DEP, mas não tem ASLR. Isso permite que um ataque possa ser construído no Windows 2003 ultrapassando as defesas de estouro de pilha.

6. O Windows 2000 Server não tem firewall. O Windows Server 2003 tem um firewall mas ele vem desligado por default.

Com base nessa análise algumas mudanças estão sendo feitas no processo. O treinamento dos desenvolvedores vai incluir conteúdo específico para identificar corretamente o nível de acesso de cada interface do sistema, e uma ferramenta está sendo desenvolvida para listar todas as interfaces RPC e a autorização requerida. O time que desenvolve as nossas ferramentas de análise de código estática está trabalhando para incluir nelas a validação deste tipo de estouro de buffer. O Windows Server 2008 inclui /GS, DEP e ASLR, em versões revistas e melhoradas, para proteger o servidor DNS contra os estouros de buffer. E o Windows Server 2008 vem com o firewall habilitado por default e integrado com autenticação IPsec.

Em um post anterior eu disse que, em relação a uma comparação do número de vulnerabilidades entre sistemas operacionais, a verdadeira pergunta a ser feita era o que o fornecedor de cada sistema operacional está fazendo para diminuir o número de vulnerabilidades de segurança. Eu acrescentaria agora uma outra, a ser feita a cada correção de segurança que você recebe: o que o seu fornecedor está fazendo para que uma vulnerabilidade como essa não aconteça de novo no futuro?