Cadre pour l'automatisation de la découverte cible floue avec analyse statique
Les chercheurs en vulnérabilité effectuant des évaluations de sécurité sur des logiciels exploiteront souvent les capacités de la couverture guidée par des outils puissants comme AFL ++ et Libfuzzer. Ceci est important car il automatise le processus Bughunting et révèle rapidement des conditions exploitables dans les cibles. Cependant, lorsqu'ils rencontrent des bases de code importantes et complexes ou des binaires de source fermée, les chercheurs doivent consacrer minutieusement le temps pour les auditer et les insensés manuellement pour identifier les fonctions où l'exploration basée sur le fuzz peut être utile.
Fuzzable est un cadre qui intègre à la fois le code source C / C ++ et les binaires pour aider les chercheurs en vulnérabilité à identifier les cibles de fonction viables pour le fuzz. 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 cadre 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 le cadre d'un pipeline de fuzzing continu, tel que le projet Oss-Fuzz de Google.
En plus de fonctionner en tant qu'outil autonome, Fuzzable est également intégré en tant que plugin pour le désassembleur ninja binaire, avec le support pour d'autres backends de démontage en cours de développement.
Consultez le billet de blog original détaillant l'outil ici, qui met en évidence les spécifications techniques de l'heuristique de l'analyse statique et comment cet outil s'est produit. Cet outil est également présenté chez Black Hat Arsenal USA 2022.
Certaines cibles binaires peuvent nécessiter une certaine désinfecture (c.-à-d. L'appariement de signature ou l'identification des fonctions de l'inlinaison), et donc Fuzzable utilise principalement le ninja binaire comme backend de démontage en raison de sa capacité à résoudre efficacement ces problèmes. Par conséquent, il peut être utilisé à la fois en tant qu'outil autonome et un plugin.
Étant donné que le ninja binaire n'est pas accessible à tous et qu'il peut y avoir une demande à utiliser pour les évaluations de sécurité et potentiellement à l'échelle dans le cloud, un backend de secours ANGR est également pris en charge. Je prévois également d'incorporer d'autres démonts sur la route (priorité: Ghidra).
Si vous avez une publicité ninja binaire, assurez-vous d'installer l'API pour une utilisation sans tête autonome:
$ python3 /Applications/Binary Ninja.app/Contents/Resources/scripts/install_api.py
Installer avec pip :
$ pip install fuzzable
Nous utilisons la poésie pour la gestion et le bâtiment des dépendances. Pour faire une construction manuelle, clonez le référentiel 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 désormais analyser les binaires et / ou le 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 le marché binaire du plugin Ninja en allant dans Binary Ninja > Manage Plugins et la recherche. Voici un exemple du plugin Fuzzable en cours d'exécution, de la précision d'identification des cibles pour le fuzzing et une nouvelle évaluation de la vulnérabilité:

Fuzzable est livré avec diverses options pour mieux régler votre analyse. Plus sera pris en charge dans les plans futurs et toutes les demandes de fonctionnalités faites.
Pour déterminer la fuzzabilité, Fuzzable utilise plusieurs heuristiques pour déterminer quelles cibles sont les plus viables à cibler pour l'analyse dynamique. Ces heuristiques sont toutes pondérées différemment en utilisant la bibliothèque Scikit-Critria, qui utilise une analyse de décision multi-critères pour déterminer les meilleurs candidats. Ces mesures et y ont-elles des poids peuvent être vues ici:
| Heuristique | Description | Poids |
|---|---|---|
| Nom amical fuzz | Le nom du symbole implique un comportement qui ingère une entrée de fichier / tampon | 0.3 |
| Puits à risque | Arguments qui se déroulent dans les appels risqués (c'est-à-dire memcpy) | 0.3 |
| Boucles naturelles | Nombre de boucles détectées avec la frontière de dominance | 0,05 |
| Complexité cyclomatique | Complexité de la cible de fonction basée sur les arêtes + nœuds | 0,05 |
| Profondeur de couverture | Nombre de callees La cible traverse | 0.3 |
Comme mentionné, consultez le billet de blog technique pour un examen plus approfondi sur pourquoi et comment ces mesures sont utilisées.
De nombreuses métriques ont été largement inspirées par l'œuvre originale de Vincenzo Iozzo dans la fuzzing à 0 connaissance.
Chaque objectif que vous souhaitez analyser est diversifié et Fuzzable ne pourra pas tenir compte de chaque comportement de cas de bord dans l'objectif du programme. Ainsi, il peut être important pendant l'analyse de régler ces poids de manière appropriée pour voir si différents résultats ont plus de sens pour votre cas d'utilisation. Pour régler 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 cibles de fonction en fonction des critères suivants:
static et qui ne sont pas exposés par le biais d'en-têtes. Pour voir les appels qui ont été filtrés par Fuzzable , définissez l'indicateur --list_ignored :
$ fuzzable analyze --list-ignored <TARGET>
Dans Binary Ninja, vous pouvez transformer ce paramètre dans Settings > Fuzzable > List Ignored Calls .
Dans le cas où Fuzzable filtre faussement les appels importants qui doivent être analysés, il est recommandé d'utiliser --include-* Arguments pour les inclure pendant la course:
# include ALL non top-level calls that were filtered out
$ fuzzable analyze --include-nontop <TARGET>
# include specific symbols that were filtered out
$ fuzzable analyze --include-sym <SYM> <TARGET>
Dans le ninja binaire, cela est pris en charge via Settings > Fuzzable > Include non-top level calls Symbols to Exclude .
Maintenant que vous avez trouvé vos candidats idéaux à Fuzz, Fuzzable vous aidera également à générer des harnais de fuzzing qui sont (presque) prêts à instrument et à compiler pour une utilisation avec un Fuzzer basé sur des fichiers (c.-à-d. AFL ++, Honggfuzz) ou une flou en mémoire (Libfuzzer). Pour ce faire dans la CLI:
# generate harness from a candidate
$ fuzzable create-harness target --symbol-name=some_unsafe_call
# make minimal and necessary modifications to the harness
$ vim target_some_unsafe_call_harness.cpp
# example compilation for AFL-QEMU, which is specified in the comments of the generated harness
$ clang target_some_unsafe_call_harness.cpp -no-pie -o target_some_unsafe_call_harness -ldl
# create your base seeds, ideally should be more well-formed for input
$ mkdir in/
$ echo "seed" >> in/seed
# start black box fuzzing
$ afl-fuzz -Q -m none -i in/ -o out/ -- ./target_some_unsafe_call_harness
Si cette cible est une base de code source, le modèle de source générique sera utilisé.
Si la cible est un binaire, le modèle générique de boîte noire sera utilisé, qui peut idéalement être utilisé avec un mode d'émulation de fuzzing comme AFL-Qemu. Une copie du binaire sera également créée en tant qu'objet partagé si le symbole n'est pas exporté directement pour être dlopen à l'aide de LIEF.
Pour le moment, cette fonctionnalité est assez rudimentaire, car elle créera simplement un harnais C ++ autonome peuplé des paramètres appropriés, et ne sera pas généré automatiquement le code qui est nécessaire pour tous les comportements d'exécution (c'est-à-dire instanciation et libération des structures). Cependant, les modèles créés pour Fuzzable devraient vous faire fonctionner rapidement. Voici quelques fonctionnalités ambitieuses que je voudrais mettre en œuvre sur la route:
Fuzzable prend en charge la génération de rapports dans divers formats. Les actuels qui sont pris en charge sont JSON, CSV et Markdown. Cela peut être utile si vous utilisez cela dans le cadre de l'automatisation où vous souhaitez ingérer la sortie dans un format sérialisable.
Dans la CLI, passez simplement l'argument --export avec un nom de fichier avec l'extension appropriée:
$ fuzzable analyze --export=report.json <TARGET>
Dans Binary Ninja, accédez à Plugins > Fuzzable > Export Fuzzability Report > ... et sélectionnez le format vers lequel vous souhaitez exporter et le chemin auquel vous souhaitez l'écrire.
Cet outil sera développé en permanence et toute aide de Mantainers externes est appréciée!
Fuzzable est autorisé sous la licence du MIT.