Fuzzing

Origem: Wikipédia, a enciclopédia livre.
Ir para: navegação, pesquisa
Question book.svg
Esta página ou secção não cita nenhuma fonte ou referência, o que compromete sua credibilidade (desde dezembro de 2011).
Por favor, melhore este artigo providenciando fontes fiáveis e independentes, inserindo-as no corpo do texto por meio de notas de rodapé. Encontre fontes: Googlenotícias, livros, acadêmicoScirusBing. Veja como referenciar e citar as fontes.
Wikitext.svg
Este artigo ou seção precisa ser wikificado (desde dezembro de 2011).
Por favor ajude a formatar este artigo de acordo com as diretrizes estabelecidas no livro de estilo.

Fuzzing é uma técnica de testes de software, frequentemente automatizada ou semi-automatizada, que envolve prover inválidos, inesperados e aleatórios dados como entradas para programas de computador. O programa é então monitorado, analisando exceções como erros em tempo de execução. Fuzzing é uma técnica comumente utilizada para testar problemas de segurança em softwares ou sistemas computacionais.

O termo tem origem em um projeto da Universidade de Wisconsin em 1988, embora tenham sido utilizadas técnicas semelhantes na área de garantia de qualidade, onde são referidas como testes de robustez, testes de sintaxe ou testes de negação. Existem duas formas de programas fuzzing: baseados em mutação e baseados em geração, que podem ser empregadas como testes de caixa branca, cinza e preta. Os maiores alvos para este tipo de teste são os formatos de arquivos e protocolos de rede, mas qualquer tipo de entrada de programa pode ser criada. Entradas interessantes incluem, vaiáveis de ambiente, eventos de teclado e mouse, e chamadas de API. Até items normalmente não considerados "entrada" podem ser gerados, ou fuzificados, como o conteúdo de banco de dados, memória compartilhada, ou trocas de contextos entre threads.

Com o objetivo de avaliar o nível de segurança, entradas que ultrapassam as barreiras de segurança são consideradas as mais interessantes. Por exemplo, é mais importante fuzificar código que realiza o upload de um arquivo por qualquer usuário que fuzificar código que analisar arquivo de configuração que é acessível a apenas um usuário privilegiado.

História[editar | editar código-fonte]

O termo "fuzzing" ou "fuzz" é originário de um projeto de classe da Universidade de Wisconsin, ensinado pelo Professor Barton Miller, em 1988. O projeto foi nomeado "Programa de Confiabilidade Utilitário em Sistemas Operacionais - O Gerador Fuzzing". O projeto desenvolveu um fuzzer baseado em linha de comando para testar a confiabilidade de programas Unix bombardeando-os com dados aleatórios até eles apresentarem um erro em tempo de execução. O teste foi repetido em 1995, expandido para incluir teste em ferramentas baseadas em GUI, protocolos de rede e APIs de bibliotecas do sistema. Trabalhos seguintes incluíram testes em sistemas baseados em linha de comando e em GUI, tanto em Windows como em Mac OS X.

Um dos primeiros exemplos de fuzzing surgiu antes de 1983. "The Monkey" ("O Macaco") foi uma aplicação Macintosh desenvolvida por Steve Capps. Ele alimentava programas Mac com eventos aleatórios e foi usado para detectar bugs no MacPaint.

Usos[editar | editar código-fonte]

Fuzzing é frequentemente empregado utilizando a metodologia de testes de caixa preta em grandes projetos de software onde existe orçamento que permite a criação para ferramentas de teste. Fuzzing é uma das técnicas que oferece uma boa relação custo-benefício.

A técnica pode apenas disponibilizar uma amostra aleatória do comportamento do sistema, e em muitos casos passar por um teste de fuzz pode apenas demonstrar que uma parte do software pode tratar exceções sem apresentar erro durante execução, do que se comportar devidamente. Isto significa que fuzzing indica apenas uma garantia da qualidade geral do sistema, não se trata de uma técnica para detectar bugs, e não substitui teste exaustivos nem métodos formais.

Como uma medida grosseira de confiabilidade, fuzzing pode sugerir que partes do programa podem precisar de atenção especial, na forma de auditoria de código, aplicação de análise estática, e reescrita parcial.

Tipos de Bugs[editar | editar código-fonte]

Fuzzing também pode ser utilizado para detectar bugs e leaks de memória (quando acoplado a um debugger de memória). A metodologia é útil em grandes aplicações, onde qualquer bug que afete a segurança do uso da memória possa gerar um erro durante a execução do programa.

Já que fuzzing frequentemente gera entradas inválida, estas são usadas para testar routinas que tratam de possíveis erros, que são importantes para o software que não estam controlando estas entradas. Fuzzing poder ser pensado como uma forma de automatizar testes negativos.

Fuzzing também pode encontrar alguns tipos de bugs relacionados a corretude do programa. Por exemplo, a técnica pode ser utilizada para detectar bugs relacionados a formas de serialização incorretas gerando mensagens sempre que um serializador do programa emita algo que o mesmo parser do programa rejeita. A técnica também pode encontrar diferenças não intencionais entre duas versões de um programa ou entre duas implementações da mesma especificação.

Técnicas[editar | editar código-fonte]

Programas fuzzing são subdivididos entre duas categorias. Fuzificadores baseados em mutação modificam amostram de dados existentes para criar outros testes de dados enquanto que fuzificadores baseados em geração criam novos testes de dados baseados em modelos da entrada.

A forma mais simples de fuzzing é enviar um fluxo de bits aleatórios para o software, seja como opções em linhas de comando, pacotes de protocolos aleatoriamente modificados, ou como eventos. Esta técnica de entradas aleatórias ainda é considerada uma ferramentar poderosa para encontrar bugs em aplicações baseadas em linhas de comando, protocolos de rede, e aplicações baseadas em GUI e em serviços. Outra técnica comum que é fácil de implementar é modificar entradas existentes modificando bits movendo blocos aleatoriamente pelo arquivo. No entanto, os melhores fuzificadores possuem entendimento detalhado do formato ou protocolo sendo testado.

O entendimento pode ser baseado em uma especificação. Um fuzzer baseado em especificação envolve escrever toda a especificação na ferramenta, e então usando técnicas de geração de testes baseadas em modelo seguem a especificação adicionando dados, mensagens, e sequências. Este "fuzzing inteligente" é também conhecido como um teste de robustez, teste de sintaxe, teste de gramática, e injeção de falhas. Testes para protocolos podem ser criados heuristicamente de exemplos usando uma ferramenta como Sequitur. Estes fuzificadores podem gerar casos de teste do zero, ou eles podem modificar exemplos de conjuntos de testes ou testes reais. Eles podem se concentrar em entradas válidas ou inválidas.

Existem duas limitações de fuzzing baseados em protocolo baseados em implementações de protocolo de especificações publicadas: 1) O teste não pode proceder até que a especificação esteja relativamente madura, já que a especificação é um pre-requisito para escrever o fuzzer, e 2) muitos protocolos úteis são proprietários, ou involvem extensões proprietárias para protocolos publicados. Se o fuzzing é baseado em apenas especificações publicadas, a cobertura dos casos para novos ou proprietários protocolos será limitada ou inexistente.

Fuzzing pode ser combinado com outras técnicas de teste. Fuzzing de caixa branca usa execução simbólica e solução restrita. Fuzzing evolucionário dá um feedback da cobertura do código, efetivamente automatizando a abordagem de testes exploratórios.

Reprodução e Isolamento[editar | editar código-fonte]

Redução de casos de testes é o processo de selecionar um número de casos de teste a partir de um conjunto de casos de teste maior. A redução pode ser feita manualmente, ou usando ferramentas de software, e usualmente involve uma estratégia "dividir para conquistar" onde partes do testes são removidos um por um até que restem apenas os casos de testes essenciais para a cobertura do programa.

Os softwares de fuzzing frequentemente registram as entradas de dados que produz, usualmente antes de aplicar ao software. Se o computador apresenta um erro durante sua execução, o teste é preservado. Se o fluxo de dados gerados é pseudo-aleatório, o valor semente pode ser armazenado para reproduzir a tentativa de fuzzing. Se um bug é detectado, algum software de fuzzing irá auxiliar na construção do caso de teste, que pode ser utilizado para debugging.

Diferenças entre o fuzzing caixa preta de aplicações Web e Desktop[editar | editar código-fonte]

O fuzzing black-box de aplicações Web tem uma grande desvantagem em relação ao de aplicações Desktop, que é a impossibilidade de acesso ao código server-side da aplicação. Esse código nunca é disponibilizado para os usuários, exceto quando alguma vulnerabilidade descoberta na aplicação permite o download de qualquer arquivo do servidor. O acesso ao código da aplicação favoreceria a utilização de várias técnicas de teste de software, que vão da análise da cobertura do código obtida com a execução de um caso de teste, até algoritmos para a geração de casos de teste com maior probabilidade de detectar vulnerabilidades.

Já no fuzzing black-box de aplicações Desktop, é sempre possível analisar o código nativo ou bytecode do executável, o que permite uma conversão para o fuzzing white-box dada a capacidade de se realizar análises sobre esse tipo de código. Com isso, consegue-se aplicar várias técnicas para obter uma melhor cobertura do código da aplicação, como a Execução Simbólica, que têm sido bastante utilizada em pesquisas acadêmicas [11-13] e em algumas ferramentas comerciais ou Open Source [2].


Vantagens e Desvantagens[editar | editar código-fonte]

O principal problema com a técnica de fuzzing para encontrar falhas em programas é que ela normalmente encontra apenas falhas simples. A complexidade computacional do problema de teste de software é de ordem exponencial (O(c^n), c > 1) e todo fuzificador utiliza cortes na sua busca para encontrar algo interessante no tempo que seja razoável para uma pessoa. Um fuzificador pode ter uma cobertura de código ruim; por exemplo, se a entrada inclui um checksum que não é propriamente atualizado para combinar com outras mudanças aleatórias, apenas o código de validação do checksum será verificado. Ferramentas de cobertura de código são frequentemente usadas para estimar o quão "bem" um fuzificador funciona, mas estes não são meios precisos para avaliar a qualidade do fuzificador. Pode se esperar que cada fuzificador encontre um conjunto diferente de bugs.

Por outro lado, bugs encontrados utilizando fuzzing são normalmente severos, bugs que realmente podem ser explorados por um atacante real. A técnica de fuzzing tornou-se bastante conhecida para assegurar a segurança em softwares, mas também passou a ser explorada por atacantes para detectar falhas em programas. Nesse problema é que se encontra uma grande vantagem da auditoria de código binário ou fonte, a injeçaõ de falhas, que pode ser difícil de se detectar por softwares que realizam fuzzing.

A aleatoriedade da entradas usadas é frequentemente vista como uma desvantagem, assim como seguir valores limites com entradas aleatórias é muito improvável.

Fuzzing é bastante importante na área de segurança de software e na criação de software seguro porque costuma encontrar defeitos que humanos não conseguiriam detectar com facilidade, e também não conseguiriam encontrar casos de testes manualmente que pudessem detectar a falha.

Ver também[editar | editar código-fonte]

  • [1] Boundary Value Analysis

Bibliografia[editar | editar código-fonte]

  • ISBN 978-1-59693-214-2, Fuzzing for Software Security Testing and Quality Assurance, Ari Takanen, Jared D. DeMott, Charles Miller

Ligações externas[editar | editar código-fonte]

Portal A Wikipédia possui o portal:
  • Software Testing