
Statisches Analyse-Framework, das fuzzbare Funktionsziele in Quellcode und Binärdateien identifiziert, Harness-Vorlagen generiert und sich mit AFL++ und libFuzzer für die automatisierte Schwachstellenerkennung integriert.
Framework zur Automatisierung der Erkennung von Fuzzable-Zielen mittels statischer Analyse

Sicherheitsforscher, die Sicherheitsbewertungen von Software durchführen, nutzen oft die Möglichkeiten des abdeckungsgesteuerten Fuzzings mit leistungsstarken Tools wie AFL++ und libFuzzer. Dies ist wichtig, da es die Fehlersuche automatisiert und ausbeutbare Bedingungen in Zielen schnell aufdeckt. Bei großen und komplexen Codebasen oder Closed-Source-Binärdateien müssen Forscher jedoch mühsam Zeit in manuelle Audits und Reverse Engineering investieren, um Funktionen zu identifizieren, bei denen eine fuzzing-basierte Erkundung nützlich sein kann.
Fuzzable ist ein Framework, das sowohl mit C/C++-Quellcode als auch mit Binärdateien integriert wird, um Sicherheitsforscher bei der Identifizierung von Funktionszielen zu unterstützen, die für das Fuzzing geeignet sind. Dies geschieht durch die Anwendung mehrerer auf statischer Analyse basierender Heuristiken, um riskantes Verhalten in der Software und die Funktionen, die diese ausführen, zu lokalisieren. Forscher können das Framework dann nutzen, um grundlegende Harness-Vorlagen zu generieren, die entweder zur Jagd nach Schwachstellen oder zur Integration in eine kontinuierliche Fuzzing-Pipeline wie Googles oss-fuzz-Projekt verwendet werden können.
Neben der Verwendung als eigenständiges Tool ist Fuzzable auch als Plugin für den Binary Ninja-Disassembler integriert, wobei die Unterstützung für andere Disassemblierungs-Backends entwickelt wird.
Schauen Sie sich den ursprünglichen Blogbeitrag an, der das Tool detailliert beschreibt, hier, der die technischen Spezifikationen der statischen Analyseheuristiken und die Entstehungsgeschichte dieses Tools hervorhebt. Dieses Tool wird auch auf der Black Hat Arsenal USA 2022 vorgestellt.
Einige Binärziele erfordern möglicherweise eine Bereinigung (z.B. Signatur-Matching oder Identifizierung von Funktionen aus Inlining). Daher verwendet fuzzable primär Binary Ninja als Disassemblierungs-Backend, da es diese Probleme effektiv lösen kann. Daher kann es sowohl als eigenständiges Tool als auch als Plugin eingesetzt werden.
Da Binary Ninja nicht für alle zugänglich ist und es eine Nachfrage nach Nutzung für Sicherheitsbewertungen und möglicherweise Skalierung in der Cloud geben könnte, wird auch ein angr Fallback-Backend unterstützt. Ich beabsichtige, in Zukunft auch weitere Disassembler einzubinden (Priorität: Ghidra).
Wenn Sie Binary Ninja Commercial besitzen, installieren Sie die API für eigenständige Headless-Nutzung:
$ python3 /Applications/Binary\ Ninja.app/Contents/Resources/scripts/install_api.py
Installation mit pip:
$ pip install fuzzable
Wir verwenden poetry für die Abhängigkeitsverwaltung und den Build. Für einen manuellen Build klonen Sie das Repository mit den Drittanbieter-Modulen:
$ git clone --recursive https://github.com/ex0dus-0x/fuzzable
So installieren Sie manuell:
$ cd fuzzable/
# ohne poetry
$ pip install .
# mit poetry
$ poetry install
# mit poetry für eine Entwicklungsumgebung (virtualenv)
$ poetry shell
Sie können nun Binär- und/oder Quellcode mit dem Tool analysieren:
# Analyse einer einzelnen Shared-Object-Bibliothek (Binär)
$ fuzzable analyze examples/binaries/libbasic.so
# Analyse einer einzelnen C-Quelldatei
$ fuzzable analyze examples/source/libbasic.c
# Analyse eines Arbeitsbereichs mit mehreren C/C++-Dateien und Headern
$ fuzzable analyze examples/source/source_bundle/
fuzzable kann einfach über den Binary Ninja Plugin-Marktplatz installiert werden, indem Sie zu Binary Ninja > Manage Plugins gehen und danach suchen. Hier ist ein Beispiel des fuzzable-Plugins in Aktion, das Ziele zum Fuzzing und zur weiteren Schwachstellenbewertung genau identifiziert:

fuzzable bietet verschiedene Optionen zur besseren Anpassung Ihrer Analyse. In zukünftigen Plänen werden weitere Optionen sowie etwaige Feature-Anfragen unterstützt.
Um die Fuzzbarkeit zu bestimmen, verwendet fuzzable mehrere Heuristiken, um die vielversprechendsten Ziele für die dynamische Analyse zu ermitteln. Diese Heuristiken werden mit der Bibliothek scikit-criteria unterschiedlich gewichtet, die eine Multi-Kriterien-Entscheidungsanalyse verwendet, um die besten Kandidaten zu ermitteln. Diese Metriken und ihre Gewichte sind hier zu sehen:
| Heuristik | Beschreibung | Gewicht |
|---|---|---|
| Fuzz-freundlicher Name | Symbolname deutet auf Verhalten hin, das Datei-/Puffereingaben aufnimmt | 0.3 |
| Riskante Senken | Argumente, die in riskante Aufrufe (z. B. memcpy) fließen | 0.3 |
| Natürliche Schleifen | Anzahl der mit der Dominanzgrenze erkannten Schleifen | 0.05 |
| Zyklomatische Komplexität | Komplexität des Funktionsziels basierend auf Kanten + Knoten | 0.05 |
| Abdeckungstiefe | Anzahl der Callees, die das Ziel durchläuft | 0.3 |
Wie bereits erwähnt, schauen Sie sich den technischen Blogbeitrag für einen tieferen Einblick, warum und wie diese Metriken verwendet werden.
Viele Metriken wurden stark von Vincenzo Iozzo's ursprünglicher Arbeit zum 0-Knowledge-Fuzzing inspiriert.
Jedes Ziel, das Sie analysieren möchten, ist vielfältig, und fuzzable wird nicht jedes Randfallverhalten im Programmziel berücksichtigen können. Daher kann es während der Analyse wichtig sein, diese Gewichte entsprechend anzupassen, um zu sehen, ob andere Ergebnisse für Ihren Anwendungsfall sinnvoller sind. Um diese Gewichte in der CLI anzupassen, geben Sie einfach das Argument --score-weights an:
$ fuzzable analyze <TARGET> --score-weights=0.2,0.2,0.2,0.2,0.2
Standardmäßig filtert fuzzable Funktionsziele basierend auf den folgenden Kriterien aus: