BrFuzzer: Um Fuzzer Distribuído para Navegadores

Transcrição

BrFuzzer: Um Fuzzer Distribuído para Navegadores
BrFuzzer: Um Fuzzer Distribuído para Navegadores
Gabriel Quadros, Ramon Pires, Marlos Marques
Departamento de Ciências Exatas
Universidade Estadual do Sudoeste da Bahia (UESB)
Estrada do Bem Querer, Km 4 – Vitória da Conquista – BA - Brasil
{gquadrossilva, pires.ramon, marlos.uesb}@gmail.com
Abstract. Fuzz testing has gained popularity in recent years as an efficient
method for finding vulnerabilities. Currently there are fuzzers for various file
formats that are used to test browsers, but they were created to run in
isolation and can not be used to divide the tasks among multiple browsers.
Even the new distributed solutions still require the installation of traditional
software testing. This paper presents a distributed fuzzer for browsers, which
in addition to harness the computational power of multiple machines requires
no software installation on the client to be tested.
Resumo. O teste de fuzzing tem ganhado popularidade nos últimos anos como
um método eficiente para encontrar vulnerabilidades. Atualmente existem
fuzzers para diversos formatos de arquivo que são usados para testar
navegadores, mas eles foram criados para executar de forma isolada, não
podendo ser usados para dividir as tarefas de teste entre vários navegadores.
Mesmo as novas soluções distribuídas ainda exigem a instalação tradicional
do software de teste. Este artigo apresenta um fuzzer distribuído para
navegadores, que além de aproveitar o poder computacional de várias
máquinas não necessita da instalação de software no cliente a ser testado.
1. Introdução
Fuzzing, prática realizada por desenvolvedores de software e pesquisadores de
vulnerabilidades, consiste na busca das mais variadas vulnerabilidades através da
inserção de dados na entrada do software a ser testado. Com o fuzzing, dados, válidos ou
não, são enviados para qualquer tipo de mecanismo de entrada, visando a verificação do
comportamento da aplicação com os dados submetidos e a detecção das
vulnerabilidades.
Em março de 2010, a Microsoft divulgou a utilização de uma nova técnica de
fuzzing distribuído (Distributed Fuzzing Framework), patenteada pela própria empresa
[Conger et al. 2010]. Diferentemente da técnica simplificada de fuzzing, onde apenas
uma máquina era encarregada de executar as milhões de iterações, o fuzzing distribuído
pode contar com a utilização de um grande número de computadores aos quais são
distribuídas as operações de teste a serem realizadas.
Segundo Tom Gallagher, líder do time de Testes de Segurança do Microsoft
Office, foram encontrados mais de 1800 bugs no Office 2010 através da execução de
milhões de testes de fuzzing. Os testes contaram com a utilização não apenas das
3
4
Workshop de Trabalhos de Iniciação Científica e de Graduação (WTICG)
máquinas dos laboratórios, mas também dos demais computadores pertencentes à
empresa que estivessem ociosos. Softwares clientes, instalados em sistemas de toda a
rede da Microsoft, automaticamente entravam em ação quando os computadores
estavam ociosos, principalmente em finais de semana, para executar testes de fuzzing.
As vulnerabilidades em navegadores estão entre as mais pesquisadas do mercado
atualmente, pois com o crescimento das aplicações Web, o navegador se tornou o alvo
de frequentes ataques nos últimos anos [TippingPoint 2005, Miller 2007, Amini 2009].
A técnica utilizada anteriormente pela Microsoft exigia que um único computador fosse
empregado na execução dos testes. Com a utilização do DFF é possível o
desenvolvimento de um fuzzer distribuído que deve ser instalado em diferentes
máquinas e possibilita a divisão dos testes entre vários navegadores.
Com base na ideia do fuzzing distribuído este trabalho propõe o desenvolvimento
de um fuzzer capaz de dividir os casos de teste entre vários navegadores à medida que
os clientes acessam o(s) servidor(es) de teste. Desta forma, não é necessária a instalação
de nenhum software no cliente a ser testado. Quando analisado durante a execução de
um caso de teste, o código vulnerável provoca a quebra do processo do navegador. O
tipo de vulnerabilidade comumente encontrada com esse tipo de fuzzer é de corrupção
de memória, como buffer overflows [Dowd et al. 2006] e use-after-free [Dowd et al.
2006].
Este artigo é dividido em seis seções. Na seção 2, é apresentado um breve
histórico dos fuzzers para navegadores. A seção 3 descreve o BrFuzzer, um fuzzer
distribuído para navegadores, e uma visão geral do seu funcionamento. Nela também
são apresentados os algoritmos desenvolvidos para a divisão dos testes e a troca de
mensagens, os detalhes da implementação com algumas análises para situações
especiais e são discutidas algumas decisões do projeto. A seção 4 apresenta os
resultados obtidos. Finalmente, as conclusões do trabalho são mostradas na seção 5 e a
discussão dos trabalhos futuros é feita na seção 6.
2. Fuzzers para Navegadores
O primeiro fuzzer para navegador lançado publicamente foi o MangleMe [Zalewski
2004], que consistia em um script CGI que gerava conteúdo HTML mal-formado e na
época foi capaz de encontrar vulnerabilidades nos principais navegadores. Em 2005, os
pesquisadores HD Moore e Aviv Raff lançaram o fuzzer Hamachi [Moore and Raff
2005], que testava páginas HTML dinâmicas. O CSSDIE [Moore 2005] foi
desenvolvido com o objetivo de fazer fuzzing em CSS (Cascade Style Sheets).
Em 2006, HD Moore e outros pesquisadores lançaram outro fuzzer chamado
DOM-Hanoi [Moore et al. 2006], para testar elementos DOM (Document Object
Model). Esta pesquisa evoluiu para um projeto conhecido como Month of Browser Bugs
[Moore et al. 2006], que divulgava um bug dos principais navegadores por dia. Ainda
nesse ano, iniciou-se outra tendência que foi a pesquisa de vulnerabilidades em
componentes ActiveX para o navegador Internet Explorer. Foram lançados os fuzzers
COMRaider [iDefense Labs 2006] e AxMan [Moore 2006].
A partir de 2007, vários outros fuzzers capazes de testar diferentes formatos de
arquivo surgiram. Em geral, qualquer fuzzer de formatos de arquivos reconhecidos pelos
X Simpósio Brasileiro em Segurança da Informação e de Sistemas Computacionais
5
navegadores pode ser aplicado para testá-los.
Embora alguns desses fuzzers explorem formatos de arquivos diferentes e
consigam encontrar vulnerabilidades, a maioria funciona no mesmo modelo: o
pesquisador abre a página no navegador e essa página vai sendo carregada com novos
códigos até que o navegador quebre. Esta tarefa é executada em um navegador de cada
vez. Além disso, o monitoramento do navegador é deixado por conta do pesquisador,
que deve iniciá-lo dentro de um depurador para ver as exceções geradas.
3. BrFuzzer: Um Fuzzer Distribuído para Navegadores
Até o presente momento, nenhum dos fuzzers divulgados faz uso de técnicas de
sistemas distribuídos para dividir os testes entre vários navegadores. Neste trabalho, foi
desenvolvido um fuzzer chamado BrFuzzer, capaz de tratar as requisições de vários
navegadores e distribuir os casos de teste previamente gerados e armazenados por um
ou vários servidores entre eles.
Ao contrário do fuzzer desenvolvido pela Microsoft, que faz uso de um software
instalado em cada cliente para monitorar o programa que está sendo testado e identificar
quando ocorre uma quebra, o BrFuzzer utiliza código JavaScript para requisitar e
executar os casos de teste baixados do servidor. Esse código é executado a partir do
momento em que o cliente abre a página de teste no servidor usando um navegador.
Por rodar dentro do navegador, esse código JavaScript não tem nenhum
privilégio para monitorar a execução do navegador e detectar exceções. Para lidar com
essa limitação, foram desenvolvidos alguns algoritmos para regular a troca de
mensagens entre os navegadores e o(s) servidor(es). A premissa desses algoritmos é que
quando ocorre uma quebra do navegador, o usuário ou o próprio sistema operacional irá
eventualmente reiniciar o processo e assim é possível testar o mesmo caso de teste por
um determinado número de vezes. Esse ciclo teste-quebra-reinício se repete até que um
número máximo de tentativas de execução de um caso de teste seja alcançado e ele seja
classificado como possível vulnerabilidade.
3.1. Algoritmos para a Distribuição dos Testes
Para a representação dos algoritmos a seguir, um caso de teste é definido como um par
<ID, caso>.
Algoritmo do Cliente
O Algoritmo 1 apresenta os passos que devem ser executados no cliente, isto é, no
navegador. Para isto, é feito o uso de cookies para identificar quais foram os casos de
teste executados que causaram a quebra do navegador e, posteriormente, executar
novamente esses mesmos casos de teste.
O navegador do cliente começa a executar esse algoritmo a partir do momento
em que acessa a página principal do(s) servidor(es).
6
Workshop de Trabalhos de Iniciação Científica e de Graduação (WTICG)
Enquanto verdadeiro
1.
Solicita novo caso de teste do servidor
2.
Se recebeu um caso de teste então
i.
Armazena o ID do caso de teste em um local que persista após uma possível quebra do
navegador
ii. Executa o caso de teste
iii. Envia o ID do caso de teste testado com sucesso para o servidor
iv. Apaga o ID armazenado anteriormente
Algoritmo 1. Algoritmo do cliente
Algoritmo do Servidor
O Algoritmo 2 apresenta os passos que devem ser executados no(s) servidor(es) para
servir os casos de teste aos clientes. Já o Algoritmo 3, apresenta os passos para marcar
os casos de teste que foram executados com sucesso e, consequentemente, não
detectaram uma vulnerabilidade. No intuito de organizar a execução dos testes, é
sugerida a implementação desse algoritmo em uma interface de comunicação (página
Web) diferente da usada no Algoritmo 2.
Enquanto verdadeiro
1.
Recebe uma requisição do cliente
2.
Se for recebido o ID de um caso de teste então
i.
Incrementa o número de tentativas de teste desse caso no banco de dados
ii. Se o número de tentativas de teste desse caso for igual ao número de tentativas
máximo definido, então
a)
Marca esse caso de teste como “vulnerabilidade encontrada”
b) Identifica qual é o navegador do cliente e sua versão
c)
Envia um novo caso de teste ainda não testado nesse tipo de navegador
iii. Senão
a)
3.
Envia o mesmo caso de teste para o cliente
Senão
i.
Identifica qual é o navegador do cliente e sua versão
ii. Envia um novo caso de teste ainda não testado nesse tipo de navegador
Algoritmo 2. Algoritmo para distribuição dos testes
X Simpósio Brasileiro em Segurança da Informação e de Sistemas Computacionais
7
Enquanto verdadeiro
1.
Recebe do cliente o ID de um caso de teste
2.
Marca o caso de teste como “testado”
Algoritmo 3. Algoritmo para marcação dos casos de teste que não descobriram
vulnerabilidades
3.2. Implementação
O Algoritmo 1 foi implementado com JavaScript, que está presente na página principal
do(s) servidor(es). As requisições ao(s) servidor(es) foram implementadas com
XMLHttpRequest, para que a página não precise ser recarregada toda vez que for
solicitar um novo caso.
Para armazenar os IDs dos casos de testes, foi usada a funcionalidade de cookies
implementada pelos navegadores. Dessa forma, após uma quebra do processo, o ID do
último caso de teste executado fica armazenado no cookie.
Os Algoritmos 2 e 3, junto com alguns utilitários como um visualizador do
estado dos casos de teste e um gerador de casos de teste, foram implementados como
páginas Web na linguagem PHP, rodando sobre um servidor Apache. O banco de dados
usado foi o PostgreSQL.
Análise de Situações Especiais
Foram feitas algumas análises dos algoritmos para algumas situações especiais:
Se o navegador do usuário for finalizado durante a execução de um caso de teste,
o servidor não incrementa o número de tentativas desse caso.
Se o usuário reiniciar o navegador, podem ocorrer as seguintes situações:
1. O navegador abre a página principal do servidor normalmente e reinicia os
testes.
◦ Caso o cookie não tenha sido deletado intencionalmente, ele será enviado
para o servidor quando o cliente requisitar um novo caso de teste. O servidor
incrementará o número de tentativas de teste desse caso e enviará o mesmo
caso de teste para esse navegador.
◦ Caso o cookie tenha sido deletado intencionalmente, o servidor envia um
novo caso de teste.
2. O navegador não abre a página principal do servidor automaticamente. Nada
acontece no servidor e o número de tentativas de teste do caso não é
incrementado.
O navegador que tem seus cookies apagados quando reiniciado, vai contribuir
para identificar apenas os testes que não encontram vulnerabilidades. Isto ocorre porque
8
Workshop de Trabalhos de Iniciação Científica e de Graduação (WTICG)
os testes que causaram algum problema vão continuar como "não testados" e
eventualmente serão enviados para serem testados em outros navegadores.
3.3. Geração dos Casos de Teste
O tipo dos casos de teste deve ser escolhido de acordo com a funcionalidade do
navegador que se deseja testar. Por exemplo, pode ser testado JavaScript, HTML, CSS,
JPEG, GIF, etc. No caso do BrFuzzer, foi implementado um script para gerar trechos de
código JavaScript.
Para gerar os casos de teste, pode ser usado qualquer um dos métodos
tradicionais de geração de casos de teste para fuzzing, que são: random, mutation-based
e generation-based [Sutton et al. 2007]. Tais casos podem ser gerados previamente ou
por demanda.
É possível implementar um método de geração feedback-based tomando como
base o número de tentativas feitas pelo navegador para executar um caso de teste.
Quando um caso de teste começar a provocar várias tentativas, ele é usado como fonte
para gerar outros casos de teste.
3.4. Organização do Servidor
Com os algoritmos desenvolvidos, o servidor pode ser replicado em várias máquinas
para resolver um possível problema de gargalo caso o número de clientes aumente
consideravelmente. Uma das técnicas que podem ser utilizadas para gerenciar a
alocação de conexões dos clientes para os servidores é o DNS Round-Robin [RFC
1794], na qual um único domínio está associado com múltiplos endereços IP.
Ao utilizar esta técnica para a resolução do nome de um domínio na Web, o
navegador recebe uma lista de endereços e normalmente escolhe o primeiro endereço da
lista. Usando um servidor DNS capaz de circular as entradas da lista de endereços,
consegue-se uma distribuição das requisições entre os vários servidores [Albitz and Liu
2006].
Outras técnicas de distribuição baseadas no gerenciamento de servidores
replicados também podem ser usadas.
4. Resultados Obtidos
O BrFuzzer foi testado com sucesso nos navegadores Internet Explorer 8, Firefox nas
versões 3.5 e 3.6, Opera 10 e Chrome nas versões 5.0 e 6.0. Foram gerados vários casos
de teste para o fuzzing dos interpretadores de JavaScript presentes nesses navegadores.
Percebeu-se que o uso de navegadores do mesmo tipo e versão aumentava
proporcionalmente a velocidade com que os testes eram realizados, dado que os casos
de teste estavam sendo divididos entre eles (Figura 1). Um navegador não receberia um
caso de teste já testado por outro navegador do mesmo tipo e versão.
Além disso, ao acessar a página principal do(s) servidor(es) com navegadores de
tipos e versões diferentes, os testes também foram executados com sucesso.
X Simpósio Brasileiro em Segurança da Informação e de Sistemas Computacionais
9
Figura 1. Gráfico do número de casos testados por segundo versus número de
navegadores
5. Conclusões
Com base nos resultados obtidos, conclui-se que o fuzzing distribuído para navegadores
é um método eficiente de teste, pois aproveita o poder computacional dos navegadores
dos usuários na Internet e não necessita de instalação de software adicional.
O código JavaScript que busca os casos de teste no(s) servidor(es) e os
executam pode ser embutido em qualquer página Web que queira contribuir com o
teste. Ao visitar essas páginas, os usuários podem utilizar seus serviços normalmente, ao
mesmo tempo em que os seus navegadores executam casos de teste em segundo plano.
Vale ressaltar que um código malicioso que deseja descobrir vulnerabilidades
em navegadores, pode utilizar esse método de fuzzing e incluir o código JavaScript em
um grande número de aplicações Web que estejam vulneráveis. Por exemplo, através de
estratégias do tipo Cross-site Scripting que permitem que códigos sejam inseridos numa
página dinâmica [OWASP 2010].
6. Trabalhos Futuros
O próximo passo na pesquisa será a utilização dos recursos de armazenamento local que
está sendo introduzido nos navegadores com a adição do suporte ao HTML 5 [W3C
2010], que permite que seja armazenado até 5 MB de dados no cliente.
Com esse recurso, passa a ser viável a geração independente de casos de teste no
próprio cliente, adicionando ao BrFuzzer um modo de funcionamento no qual o cliente
não busca mais os casos de teste no servidor, mas gera seus próprios casos de teste,
testa-os e envia para o servidor apenas aqueles que atingirem um determinado número
de tentativas de execução.
10
Workshop de Trabalhos de Iniciação Científica e de Graduação (WTICG)
Referências
Conger, D. J. and Srinivasamurthy, K. and Cooper, R. S. (2010) “Distributed File
Fuzzing”, http://www.faqs.org/patents/app/20080256340, June.
Miller,
C.
(2007)
“The
Legitimate
http://weis2007.econinfosec.org/papers/29.pdf, June.
Vulnerability
Market”,
Amini, P. (2009) “Mostrame la guita! Adventures in Buying Vulnerabilities”,
www.ekoparty.org/archive/2009/Mostrame_la_guita_.pdf, June.
TippingPoint (2005) “Zero Day Initiative”, http://www.zerodayinitiative.com, June.
Zalewski, M. (2004) “MangleMe”, http://freshmeat.net/projects/mangleme/, June.
Moore
H.
D.
and
Raff,
Aviv.
(2005)
http://metasploit.com/users/hdm/tools/hamachi/hamachi.html, June.
Moore H. D. (2005) “CSSDIE”,
die/cssdie.html, June.
“Hamachi”,
http://metasploit.com/users/hdm/tools/see-ess-ess-
Moore
H.
D.
et
al.
(2006)
“DOM-Hanoi”,
http://metasploit.com/users/hdm/tools/domhanoi/domhanoi.html, June.
Moore H. D. et al. (2006) “Month of Browser Bugs”, http://browserfun.blogspot.com/,
June.
iDefense Labs. (2006) “COMRaider”, http://labs.idefense.com/software/fuzzing.php,
June.
Moore, H. D. (2006) “AxMan ActiveX Fuzzer”, http://digitaloffense.net/tools/axman/,
June.
Sutton, M. and Greene A. and Amini, P. (2007) “Fuzzing: Brute Force Vulnerability
Discovery”, Addison-Wesley Professional, 1º edition.
RFC 1794 (1995) “DNS Support for Load Balancing”, http://tools.ietf.org/html/rfc1794,
June.
W3C (2010) “Web Storage”, http://dev.w3.org/html5/webstorage/, June.
OWASP (2010), “Cross-site
site_Scripting_(XSS), June.
Scripting”,
http://www.owasp.org/index.php/Cross-
Dowd M. and McDonald, J. and Schuh, J. (2006) “The Art of Software Security
Assessment: Identifying and Preventing Software Vulnerabilities”, Addison-Wesley
Professional, 1º edition.
Albitz P. and Liu C. (2006) “DNS and BIND”, O'Reilly, 5º edition, p. 250-253.