
Cadre d'analyse statique qui identifie les cibles de fonctions fuzzables dans le code source et les binaires, génère des modèles de harnais, et s'intègre avec AFL++ et libFuzzer pour la découverte automatisée de vulnérabilités.
Framework pour l'automatisation de la découverte de cibles Fuzzable avec analyse statique

Les chercheurs en vulnérabilités qui effectuent des évaluations de sécurité sur des logiciels utilisent souvent les capacités du fuzzing guidé par couverture via des outils puissants comme AFL++ et libFuzzer. C'est important car cela automatise le processus de chasse aux bugs et révèle rapidement des conditions exploitables dans les cibles. Cependant, lorsqu'ils rencontrent des bases de code volumineuses et complexes ou des binaires fermés, les chercheurs doivent consacrer laborieusement du temps à auditer manuellement et à rétro-ingénierer pour identifier les fonctions où l'exploration basée sur le fuzzing peut être utile.
Fuzzable est un framework qui s'intègre à la fois avec le code source C/C++ et les binaires pour aider les chercheurs en vulnérabilités à identifier les fonctions cibles viables pour le fuzzing. Cela se fait en appliquant plusieurs heuristiques basées sur l'analyse statique pour identifier les comportements risqués dans le logiciel et les fonctions qui les exécutent. Les chercheurs peuvent ensuite utiliser le framework pour générer des modèles de harnais de base, qui peuvent ensuite être utilisés pour chasser les vulnérabilités, ou pour être intégrés dans un pipeline de fuzzing continu, comme le projet oss-fuzz de Google.
En plus de fonctionner comme un outil autonome, Fuzzable est également intégré comme plugin pour le désassembleur Binary Ninja, avec le support d'autres backends de désassemblage en développement.
Consultez l'article de blog original détaillant l'outil, qui met en évidence les spécifications techniques des heuristiques d'analyse statique et comment cet outil a vu le jour. Cet outil est également présenté au Black Hat Arsenal USA 2022.
Certaines cibles binaires peuvent nécessiter un certain assainissement (par exemple, la correspondance de signatures, ou l'identification de fonctions à partir de l'inlining), et donc fuzzable utilise principalement Binary Ninja comme backend de désassemblage en raison de sa capacité à résoudre efficacement ces problèmes. Par conséquent, il peut être utilisé à la fois comme outil autonome et comme plugin.
Étant donné que Binary Ninja n'est pas accessible à tous et qu'il peut y avoir une demande pour l'utiliser dans le cadre d'évaluations de sécurité et éventuellement le déployer dans le cloud, un backend de fallback angr est également supporté. J'envisage d'intégrer d'autres désassembleurs à l'avenir (priorité : Ghidra).
Si vous avez Binary Ninja Commercial, assurez-vous d'installer l'API pour une utilisation autonome sans interface graphique :
$ python3 /Applications/Binary\ Ninja.app/Contents/Resources/scripts/install_api.py
Installez avec pip :
$ pip install fuzzable
Nous utilisons poetry pour la gestion des dépendances et la construction. Pour effectuer une construction manuelle, clonez le dépôt avec les modules tiers :
$ git clone --recursive https://github.com/ex0dus-0x/fuzzable
Pour installer manuellement :
$ cd fuzzable/
# without poetry
$ pip install .
# with poetry
$ poetry install
# with poetry for a development virtualenv
$ poetry shell
Vous pouvez maintenant analyser des binaires et/ou du code source avec l'outil !
# 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 peut être facilement installé via la place de marché des plugins Binary Ninja en allant dans Binary Ninja > Manage Plugins et en le recherchant. Voici un exemple du plugin fuzzable en cours d'exécution, identifiant avec précision les cibles pour le fuzzing et une évaluation ultérieure des vulnérabilités :

fuzzable est livré avec diverses options pour vous aider à mieux ajuster votre analyse. D'autres seront supportées dans les plans futurs et toute demande de fonctionnalité.
Pour déterminer la fuzzabilité, fuzzable utilise plusieurs heuristiques pour déterminer quelles cibles sont les plus viables pour l'analyse dynamique. Ces heuristiques sont toutes pondérées différemment à l'aide de la bibliothèque scikit-criteria, qui utilise l'analyse de décision multicritère pour déterminer les meilleurs candidats. Ces métriques et leurs poids peuvent être vus ici :
| Heuristique | Description | Poids |
|---|---|---|
| Nom adapté au fuzzing | Le nom du symbole implique un comportement qui ingère une entrée de fichier/tampon | 0.3 |
| Sinks risqués | Arguments qui alimentent des appels risqués (ex: memcpy) | 0.3 |
| Boucles naturelles | Nombre de boucles détectées avec la frontière de dominance | 0.05 |
| Complexité cyclomatique | Complexité de la fonction cible basée sur les arêtes + nœuds | 0.05 |
| Profondeur de couverture | Nombre de callees que la cible traverse | 0.3 |
Comme mentionné, consultez l'article de blog technique pour un aperçu plus approfondi de pourquoi et comment ces métriques sont utilisées.
De nombreuses métriques ont été largement inspirées par les travaux originaux de Vincenzo Iozzo sur le fuzzing à 0 connaissance.
Chaque cible que vous souhaitez analyser est diverse, et fuzzable ne pourra pas prendre en compte tous les comportements de cas limites dans la cible du programme. Ainsi, il peut être important lors de l'analyse d'ajuster ces poids de manière appropriée pour voir si différents résultats ont plus de sens pour votre cas d'utilisation. Pour ajuster ces poids dans la CLI, spécifiez simplement l'argument --score-weights :
$ fuzzable analyze <TARGET> --score-weights=0.2,0.2,0.2,0.2,0.2
Par défaut, fuzzable filtrera les fonctions cibles selon les critères suivants :