
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 --.