
Framework de fuzzing modular com uma DSL (HierarFlow) para compor loops de fuzzing a partir de primitivas reutilizáveis. Suporta AFL, libFuzzer, VUzzer e mais para descoberta automatizada de vulnerabilidades.
fuzzuf (fuzzing unification framework - framework de unificação de fuzzing) é um framework de fuzzing com sua própria DSL para descrever um loop de fuzzing através da construção de blocos de construção de primitivas de fuzzing.
Para instruções de compilação e um tutorial, siga building.md e tutorial.md.
fuzzuf permite uma definição flexível de um loop de fuzzing definido em cada fuzzer, descrevendo-o como combinações de blocos de construção com notações DSL, mantendo a extensibilidade para seu fuzzer original. Ele já possui várias implementações de fuzzers, incluindo AFL, VUzzer e libFuzzer, que podem ser ainda mais estendidas pelos usuários.
fuzzuf utiliza sua própria DSL chamada HierarFlow para declarações de loop de fuzzing. Ela é implementada sobre a linguagem C++ com a gramática projetada para se parecer com uma estrutura de árvore, a fim de descrever um loop de fuzzing como uma combinação de blocos de construção.
Com HierarFlow, podemos escrever fuzzers existentes e novos de forma organizada e limpa, pois a estrutura de um loop de fuzzing pode ser claramente exibida. Por exemplo, podemos dividir um fuzzer AFL (que já foi implementado no fuzzuf como template!) em múltiplas primitivas de fuzzing que incluem executor do PUT, mutadores (determinísticos e aleatórios), atualizador de dicionário, e assim por diante. Os usuários podem implementar cada primitiva em código C++ e conectá-las com o operador do HierarFlow para eventualmente construir um loop de fuzzing do fuzzer que desejam alcançar.
O seguinte trecho curto representa AFL no HierarFlow:
fuzz_loop << (
cull_queue
|| select_seed
);
select_seed << (
consider_skip_mut
|| retry_calibrate
|| trim_case
|| calc_score
|| apply_det_muts << (
bit_flip1 << execute << (normal_update || construct_auto_dict)
|| bit_flip_other << execute.HardLink() << normal_update.HardLink()
|| byte_flip1 << execute.HardLink() << (normal_update.HardLink()
|| construct_eff_map)
|| byte_flip_other << execute.HardLink() << normal_update.HardLink()
|| arith << execute.HardLink() << normal_update.HardLink()
|| interest << execute.HardLink() << normal_update.HardLink()
|| user_dict_overwrite << execute.HardLink() << normal_update.HardLink()
|| auto_dict_overwrite << execute.HardLink() << normal_update.HardLink()
)
|| apply_rand_muts << (
havoc << execute.HardLink() << normal_update.HardLink()
|| splicing << execute.HardLink() << normal_update.HardLink()
)
|| abandon_node
);
Isso simplesmente mostra quão flexível e poderoso é o HierarFlow. Consulte o documento para mais detalhes.
Existem principalmente quatro vantagens em escrever fuzzers no framework fuzzuf:
Pode descrever um loop de fuzzing com combinações de cada primitiva de fuzzing
fuzzuf constrói um loop de fuzzing com uma combinação de primitivas de fuzzing (uma etapa individual em um loop de fuzzing) como blocos de construção. Como cada bloco pode ser anexado, removido, substituído e reutilizado, o fuzzuf pode manter a alta modularidade de cada loop de fuzzing definido.
Loops de fuzzing flexíveis e definíveis pelo usuário
Como os frameworks de fuzzing existentes tendem a ter loops de fuzzing fixos ou embutidos no código dentro dos próprios frameworks, seus usuários não podiam manipular seus comportamentos.
fuzzuf pode atribuir e implementar uma rotina para cada primitiva de fuzzing dividida, e descrever e modificar a estrutura de um loop de fuzzing conforme o usuário desejar.
Fácil comparar um fuzzer derivado com seu original
Não é raro que pesquisadores e entusiastas de fuzzing façam fork de um fuzzer existente para implementar sua própria ideia sobre ele. De fato, muitos trabalhos acadêmicos mostraram inúmeros fuzzers baseados em AFL refletindo suas ideias. Ao aproveitar as características de bloco de construção da DSL do fuzzuf e reutilizar primitivas de fuzzing existentes, os usuários podem acelerar bastante o processo de desenvolvimento de seu novo fuzzer.
Além disso, ao comparar os diffs das DSLs entre o fuzzer original e seus derivados, as melhorias podem ser facilmente identificadas rapidamente (não apenas para os próprios usuários, mas também para revisores e outros pesquisadores).
Fuzzer AFL como template
No fuzzuf, o AFL está disponível como um template de fuzzer (C++) também. Isso significa que o custo para implementar e revisar um fuzzer novo ou existente baseado em AFL foi bastante reduzido ao utilizá-lo. Por exemplo, o AFLFast do fuzzuf é construído sobre esse template. Apenas algumas modificações nas rotinas e em uma struct que registra o estado do fuzzer são necessárias para alterar, e ele mantém o fluxo original inalterado.
fuzzuf vem com os seguintes fuzzers implementados por padrão. Para ver a visão geral e como usá-los via CLI, siga os links fornecidos abaixo.
Nota: ao usar fuzzuf via CLI, você deve separar as opções globais (opções disponíveis para todos os fuzzers) das opções locais (opções específicas do fuzzer) com --.
Consideramos migrar o framework de C++ para Rust por ser mais seguro e ter um ecossistema organizado durante o desenvolvimento. No entanto, apesar das tentativas e discussões, concluímos que não mudaríamos a linguagem. A razão é explicada em detalhes aqui.
A referência da API gerada pelo doxygen está disponível aqui.
fuzzuf é licenciado sob a GNU Affero General Public License v3.0. Alguns códigos originários de projetos externos são licenciados sob suas próprias licenças. Consulte LICENSE para detalhes.
Este projeto recebeu financiamento da Acquisition, Technology & Logistics Agency (ATLA) sob a Innovative Science and Technology Initiative for Security 2020 (JPJ004596).
| Fuzzer | Tipo | Descrição | Uso CLI | Visão Geral do Algoritmo | Modo Frida |
|---|
| AFL | Greybox | Uma reimplementação de fuzzer de propósito geral, representando um CGF. Também disponível como template para seus derivados. | Como usar a CLI AFL do fuzzuf | Visão Geral do Algoritmo | ✅ |
| AFLFast | Greybox | Uma implementação do AFLFast, utilizando um template AFL. O algoritmo tenta aumentar seu desempenho manipulando o cronograma de energia. | Uso CLI | Visão Geral do Algoritmo | ✅ |
| IJON | Greybox | Um fuzzer que pode fuzzer PUTs de maneira consciente de estado interno com anotações manuais nos PUTs. | Uso CLI | Visão Geral do Algoritmo | |
| VUzzer | Greybox | Um fuzzer baseado em mutação que adivinha estruturas de dados analisando o fluxo de controle e o fluxo de dados do PUT. | Leia Pré-requisitos primeiro, depois Uso na CLI | Visão Geral do Algoritmo | |
| libFuzzer | Greybox | CGF incluído nas bibliotecas compiler-rt do projeto LLVM. | Como usar libFuzzer no fuzzuf | O que é libFuzzer? | |
| Nezha | Greybox | Um fuzzer originário do libFuzzer que tenta encontrar defeitos no programa executando programas com implementações diferentes com a mesma entrada e comparando seus resultados de execução (fuzzing diferencial). | Como usar Nezha no fuzzuf | TBD | |
| DIE | Greybox | Um fuzzer para mecanismos JavaScript que preserva o aspecto dos casos de teste através do processo de mutação | Uso na CLI | Visão Geral do Algoritmo | |
| Nautilus | Greybox | Um fuzzer guiado por cobertura e baseado em gramática que gera casos de teste de acordo com a gramática definida pelo usuário | Uso na CLI | Visão Geral do Algoritmo | |
| MOpt | Greybox | Algoritmo baseado em Otimização por Enxame de Partículas sobre o AFL | Uso na CLI | Visão Geral do Algoritmo | |
| SymCC | Concolic | Execução Simbólica Eficiente Baseada em Compilador | TBA | TBA | |
| Eclipser | Greybox Concolic | Teste Concolic Greybox | Uso na CLI | TBA |