
Framework de análise estática que identifica alvos de funções fuzzáveis em código fonte e binários, gera modelos de harness e se integra com AFL++ e libFuzzer para descoberta automatizada de vulnerabilidades.
Framework para Automatizar a Descoberta de Alvos Fuzzable com Análise Estática

Pesquisadores de vulnerabilidades que realizam avaliações de segurança em software frequentemente aproveitam as capacidades de fuzzing guiado por cobertura por meio de ferramentas poderosas como AFL++ e libFuzzer. Isso é importante, pois automatiza o processo de caça a bugs e revela condições exploráveis em alvos rapidamente. No entanto, ao encontrar bases de código grandes e complexas ou binários de código fechado, os pesquisadores precisam dedicar tempo meticulosamente para auditar e fazer engenharia reversa manualmente, a fim de identificar funções onde a exploração baseada em fuzzing pode ser útil.
Fuzzable é um framework que se integra tanto com código-fonte C/C++ quanto com binários para auxiliar pesquisadores de vulnerabilidades a identificar funções-alvo que são viáveis para fuzzing. Isso é feito aplicando várias heurísticas baseadas em análise estática para identificar comportamentos arriscados no software e as funções que os executam. Os pesquisadores podem então usar o framework para gerar templates básicos de harness, que podem ser usados para caçar vulnerabilidades ou ser integrados como parte de um pipeline contínuo de fuzzing, como o projeto oss-fuzz do Google.
Além de funcionar como uma ferramenta autônoma, o Fuzzable também é integrado como um plugin para o desassemblador Binary Ninja, com suporte para outros backends de desmontagem em desenvolvimento.
Confira o post original do blog detalhando a ferramenta aqui, que destaca as especificações técnicas das heurísticas de análise estática e como essa ferramenta surgiu. Esta ferramenta também é apresentada no Black Hat Arsenal USA 2022.
Alguns alvos binários podem exigir alguma sanitização (ex. correspondência de assinaturas ou identificação de funções de inlining) e, portanto, o fuzzable usa principalmente o Binary Ninja como backend de desmontagem devido à sua capacidade de resolver esses problemas de forma eficaz. Portanto, pode ser utilizado tanto como ferramenta autônoma quanto como plugin.
Como o Binary Ninja não é acessível a todos e pode haver demanda para uso em avaliações de segurança e potencial escalonamento na nuvem, um backend fallback angr também é suportado. Antecipo incorporar outros desassembladores no futuro também (prioridade: Ghidra).
Se você possui o Binary Ninja Comercial, certifique-se de instalar a API para uso autônomo headless:
$ python3 /Applications/Binary\ Ninja.app/Contents/Resources/scripts/install_api.py
Instale com pip:
$ pip install fuzzable
Usamos poetry para gerenciamento de dependências e build. Para fazer um build manual, clone o repositório com os módulos de terceiros:
$ git clone --recursive https://github.com/ex0dus-0x/fuzzable
Para instalar manualmente:
$ cd fuzzable/
# without poetry
$ pip install .
# with poetry
$ poetry install
# with poetry for a development virtualenv
$ poetry shell
Agora você pode analisar binários e/ou código-fonte com a ferramenta!
# analyzing a single shared object library binary
$ fuzzable analyze examples/binaries/libbasic.so
# analyzing a single C source file
$ fuzzable analyze examples/source/libbasic.c
# analyzing a workspace with multiple C/C++ files and headers
$ fuzzable analyze examples/source/source_bundle/
fuzzable pode ser facilmente instalado através do marketplace de plugins do Binary Ninja acessando Binary Ninja > Manage Plugins e procurando por ele. Aqui está um exemplo do plugin fuzzable em execução, identificando com precisão alvos para fuzzing e avaliação adicional de vulnerabilidades:

fuzzable vem com várias opções para ajudar a ajustar melhor sua análise. Mais opções serão suportadas em planos futuros e quaisquer solicitações de funcionalidades feitas.
Para determinar a fuzzabilidade, o fuzzable utiliza várias heurísticas para determinar quais alvos são os mais viáveis para análise dinâmica. Essas heurísticas são ponderadas de forma diferente usando a biblioteca scikit-criteria, que utiliza análise de decisão multicritério para determinar os melhores candidatos. Essas métricas e seus pesos podem ser vistos aqui:
| Heurística | Descrição | Peso |
|---|---|---|
| Nome Amigável para Fuzz | Nome do símbolo implica comportamento que ingere entrada de arquivo/buffer | 0.3 |
| Sumidouros Arriscados | Argumentos que fluem para chamadas arriscadas (ex. memcpy) | 0.3 |
| Laços Naturais | Número de loops detectados com a fronteira de dominância | 0.05 |
| Complexidade Ciclomática | Complexidade do alvo da função baseada em arestas + nós | 0.05 |
| Profundidade de Cobertura | Número de funções chamadas que o alvo percorre | 0.3 |
Como mencionado, confira o post técnico do blog para uma visão mais aprofundada de por que e como essas métricas são utilizadas.
Muitas métricas foram amplamente inspiradas pelo trabalho original de Vincenzo Iozzo em fuzzing de conhecimento zero.
Cada alvo que você deseja analisar é diverso, e o fuzzable não será capaz de considerar todos os comportamentos de casos extremos no programa alvo. Assim, pode ser importante durante a análise ajustar esses pesos adequadamente para ver se resultados diferentes fazem mais sentido para o seu caso de uso. Para ajustar esses pesos na CLI, basta especificar o argumento --score-weights:
$ fuzzable analyze <TARGET> --score-weights=0.2,0.2,0.2,0.2,0.2
Por padrão, o fuzzable filtrará alvos de função com base nos seguintes critérios:
static e não são expostas por meio de cabeçalhos.