
Um fuzzer evolucionário baseado em conhecimento
Este documento tem como objetivo explicar brevemente a teoria por trás do Choronzon. Além disso, fornece detalhes sobre seus componentes internos e como é possível estender o Choronzon para atender a novos requisitos. Uma visão geral da arquitetura do Choronzon foi inicialmente apresentada na Conferência ZeroNights 2015. Uma gravação da apresentação e a apresentação de slides também estão disponíveis.
Choronzon é um fuzzer evolucionário. Ele tenta imitar o processo evolutivo para continuar produzindo melhores resultados. Para isso, possui um sistema de avaliação para classificar quais dos arquivos fuzzeados são interessantes e quais devem ser descartados.
Além disso, Choronzon é um fuzzer baseado em conhecimento. Ele utiliza informações definidas pelo usuário para ler e escrever arquivos do formato de arquivo alvo. Para se familiarizar com a terminologia do Choronzon, considere que cada arquivo é representado por um cromossomo. Os usuários devem descrever a estrutura elementar do formato de arquivo em questão. Uma visão geral de alto nível do formato de arquivo é preferível em vez de descrever cada detalhe e aspecto dele. Cada uma dessas estruturas elementares definidas pelo usuário é considerada um gene. Cada cromossomo contém uma árvore de genes e é capaz de construir o arquivo correspondente a partir dela.
Choronzon é dividido em três subsistemas: o módulo Tracer, o módulo Chromosome e o fuzzer.
Resumidamente, o componente Chromosome é usado para descrever o formato do arquivo alvo. Os usuários podem escrever seus próprios módulos para suportar formatos novos ou personalizados. Como caso de teste, um módulo PNG é fornecido com o Choronzon.
Por outro lado, o componente Tracer é responsável por monitorar a aplicação alvo e coletar várias informações sobre sua execução. Esta versão do Choronzon utiliza a ferramenta de instrumentação binária Intel's Pin para registrar os blocos básicos que foram visitados durante a execução. No entanto, Choronzon é capaz de suportar outros backends de rastreamento também. Lembre-se também de que na próxima versão do Choronzon, o Pin será substituído devido ao seu enorme impacto no desempenho.
Por último, o componente fuzzer é usado para alterar o conteúdo dos arquivos a serem testados. O módulo contém um corpus de Mutators e Recombinators. Mutators, simplesmente, alteram o arquivo como fuzzers comuns fazem. Por exemplo, realizam inversão de bytes, troca de bytes, mutação aleatória de bytes e assim por diante. Mas Choronzon possui outro recurso que não é tão comum entre fuzzers. Recombinators usam as informações sobre a estrutura do formato de arquivo, fornecidas pelo módulo Chromosome, para realizar fuzzing inteligente.
No diretório chromosome/parsers você pode encontrar o arquivo PNG.py. Este
módulo Python descreve o formato de arquivo PNG para o fuzzer. Você pode adicionar seus
módulos personalizados para outros formatos de arquivo neste diretório.
A ideia fundamental por trás do subsistema Chromosome é converter os arquivos de semente iniciais usando um Deserializer em uma árvore de Genes. Em algum momento, os Genes (fuzzeados) serão escritos em um arquivo, usando um Serializer.
Considere que no Choronzon o objetivo do módulo de análise sintática é fornecer a estrutura elementar do formato de arquivo, em vez de cada mínimo detalhe. Isso ajudará o fuzzer a construir arquivos que são principalmente íntegros, evitando saídas precoces da aplicação alvo. Além disso, esta abordagem economiza tempo, pois descrever cada aspecto do formato de arquivo consome tempo e introduz uma sobrecarga significativa de desenvolvimento.
Um novo módulo de análise sintática deve importar:
e deve implementar
No exemplo fornecido com o Choronzon, cada PNGGene corresponde a um chunk PNG. Geralmente, você pode pensar em um Gene como uma estrutura de dados elementar do formato alvo. Cada Chromosome é composto por uma árvore de Genes, e representa um arquivo único. Cada Gene deve ser capaz de produzir uma string de bytes que contenha seus dados combinados com os dados dos Genes inferiores na árvore.
O PNGSerializer deve ser capaz de produzir um arquivo (principalmente íntegro) a partir de quando uma lista de Genes é fornecida a ele. Por outro lado, PNGDeserializer deve ser capaz de analisar um arquivo válido do formato alvo e deserializá-lo em uma árvore de Genes.
Verifique chromosome/parsers/PNG.py para um exemplo comentado para o formato PNG.
O módulo Tracer é usado para desmontar a aplicação alvo (e/ou uma ou mais de suas bibliotecas). Nesta versão do Choronzon, isso é feito com o IDA. Utilizamos esta abordagem porque podemos correlacionar qualquer informação interessante da campanha de fuzzing com nossos IDBs. No entanto, podemos remover a dependência do IDA num futuro próximo para tornar o Choronzon mais portável e acessível.
Um arquivo é testado contra uma aplicação com a ajuda de um utilitário do Pin. No
diretório analyzer/coverage encontra-se o código fonte desta ferramenta Pin, que
injeta hooks no início de cada bloco básico na aplicação alvo.
Quando a execução é concluída, correlacionamos o bloco básico que foi atingido com
o bloco básico do binário. Assim, somos capazes de calcular métricas que são
valiosas para nós (cobertura, etc).
O componente Fuzzer utiliza a representação Chromosome para fuzzear um arquivo. Como mencionado anteriormente, existem dois métodos de fuzzing no Choronzon.
Para o primeiro método, Choronzon obtém o conteúdo de um ou mais genes
e aplica um dos Mutators. Mutators implementam métodos de fuzzing comuns, mas eficazes,
como mutação aleatória de bytes, definição de bit alto, troca de bytes
e muitos outros. Você também pode escrever seus próprios mutadores personalizados e adicioná-los em
fuzzers/mutators.py.
O segundo método de fuzzing é chamado recombinação. Recombinators são usados para alterar a estrutura do arquivo. Aqui está um exemplo com o formato PNG.
Arquivos PNG são compostos por chunks consecutivos que contêm quatro campos,
Vamos supor que temos um arquivo PNG que possui apenas chunks IHDR, IDAT e IEND. Sua estrutura seria assim:
[ Assinatura PNG ] [ IHDR ] [ IDAT ] [ IEND ]
Como Choronzon está ciente das estruturas básicas (ou seja, os chunks PNG), ele é capaz de alterar sua sequência. Após uma recombinação bem-sucedida, o arquivo de saída PNG fuzzeado pode ficar assim:
[ Assinatura PNG ] [ IDAT ] [ IHDR ] [ IEND ]
Choronzon contém muitas outras estratégias de recombinação que o tornam capaz de lidar até com formatos de arquivo complicados.
Choronzon foi testado com Python 2.7, Pin 3, IDA Pro 6.6 a 6.9, no Ubuntu 16.04 LTS (kernel Linux 4.4) e Windows 10.
Para executá-lo, você precisará instalar o pacote Python sortedcontainers. Você pode encontrá-lo aqui ou instalá-lo via pip.
Além disso, Choronzon precisa do IDA Pro (na verdade, sua versão de terminal). O caminho do IDA Pro deve ser especificado no seu arquivo de configuração assim:
DisassemblerPath = 'C:\\Program Files (x86)\\IDA 6.6'
Foi testado com sucesso com IDA Pro 6.6, 6.7, 6.8 e 6.9.
A ferramenta Pin de cobertura do Choronzon está localizada em analyzer/coverage e deve ser
compilada. Você pode querer verificar a documentação do Pin para detalhes, ou pode
realizar os seguintes passos:
coverage.cpp e makefile.rules para
/path/to/pin/source/tools/MyPinToolmake. Se você estiver no Windows, deve executar a linha de comando do Visual
Studio e usar o utilitário make e suas dependências do
Cygwin/path/to/choronzon/analysis/coverage o diretório recém-criado
obj-intel64 (ou obj-ia32 para sistemas de 32 bits)Para fuzzear com Choronzon, você deve fornecer um arquivo
de configuração. No diretório settings há um exemplo da configuração
do Choronzon.