
Manul ist ein abdeckungsgesteuerter paralleler Fuzzer für Open-Source- und Blackbox-Binärdateien unter Windows, Linux und macOS.

Manul ist ein abdeckungsgesteuerter paralleler Fuzzer für Open-Source- und Black-Box-Binärdateien unter Windows, Linux und macOS (Beta), geschrieben in reinem Python.
pip3 install psutil
git clone https://github.com/mxmssh/manul
cd manul
mkdir in
mkdir out
echo "AAAAAA" > in/test
python3 manul.py -i in -o out -n 4 "linux/test/test_afl @@"
sudo apt-get install gcc make git wget
git clone https://gitlab.com/akihe/radamsa.git && cd radamsa && make && sudo make install
Es ist nicht erforderlich, Radamsa unter Windows zu installieren. Manul wird auf dieser Plattform mit der nativen Radamsa-Bibliothek ausgeliefert.
| CVE-IDs | Produkt | Finder |
|---|---|---|
| CVE-2019-9631 CVE-2019-7310 CVE-2019-9959 | Poppler | Maksim Shudrak |
| CVE-2018-17019 CVE-2018-16807 CVE-2019-12175 | Bro/Zeek | Maksim Shudrak |
Wenn Sie mit Manul einen neuen Fehler gefunden haben, kontaktieren Sie mich bitte, und ich werde Sie in die Liste aufnehmen.

pip install pywin32) auf Windows-Plattform (nur für DBI-Persistenzmodus erforderlich).Derzeit unterstützt Manul zwei Arten der Instrumentierung: AFL-basiert (afl-gcc, afl-clang und afl-clang-fast) und DBI.
Instrumentieren Sie Ihr Ziel mit afl-gcc oder afl-clang-fast und Address Sanitizer (empfohlen für bessere Ergebnisse). Zum Beispiel:
CC=afl-gcc CXX=afl-g++ CFLAGS=-fsanitize=address CXXFLAGS=-fsanitize=address cmake <pfad_zu_ihrem_ziel>
make -j 8
USE_ASAN=1 CC=afl-clang-fast CXX=afl-clang-fast++ cmake <pfad_zu_ihrem_ziel>
make -j 8
Weitere Details finden Sie in diesen Anweisungen.
Sie müssen Ihr Ziel in diesem Modus nicht instrumentieren, müssen aber die neueste Version des DynamoRIO-Frameworks für Windows oder Linux herunterladen.
Manul wird mit vorcompilierten x86/x64-Clients für Linux und Windows ausgeliefert. Sie finden sie in den folgenden Ordnern:
linux/dbi_32|dbi_64/libbinafl.so (DynamoRIO-Client)
win/dbi_32|dbi_64/binafl.dll
Leider wird DynamoRIO unter macOS nicht offiziell unterstützt.
Sie finden die neuesten DynamoRIO-Releasepakete auf der DynamoRIO-Downloadseite.
Sie müssen die folgenden Zeilen in der Datei manul.config auskommentieren und den korrekten Pfad zum DynamoRIO-Launcher und -Client angeben.
# Wählen Sie das DBI-Framework, um die Abdeckung an Manul zurückzugeben ("dynamorio" oder "pin"). Beispiel: dbi = dynamorio
dbi = dynamorio
# Wenn der dbi-Parameter nicht None ist, sollten der Pfad zum DBI-Engine-Launcher und zum DBI-Client angegeben werden.
dbi_root = /home/max/DynamoRIO/bin64/drrun
dbi_client_root = /home/max/manul/linux/dbi_64/libbinafl.so
dbi_client_libs = None
Zusätzlich können Sie die Leistung Ihrer Black-Box-Fuzzing-Kampagne durch persistentes In-Memory-Fuzzing steigern. In diesem Modus sollten Sie Manul anweisen, eine bestimmte Funktion zu instrumentieren (ja, Sie müssen sie durch Disassemblieren Ihrer Binärdatei finden), und es wird diese in einer Schleife ausführen, indem Sie die folgenden Zeilen auskommentieren:
dbi_persistence_mode = 1
dbi_target_module = afl_test
dbi_target_method = open_file
#dbi_target_offset = 0x3198 # optional können Sie den Offset dieser Funktion anstelle des Namens angeben
dbi_fuzz_iterations = 1000
Die Autoren von winAFL erklären sehr gut, wie das funktioniert, hier. Manul verwendet einen großen Teil des winAFL-Instrumentierungsbibliothekscodes, um mit einem Ziel zu kommunizieren und es zu instrumentieren.
WICHTIGER HINWEIS: Sie sollten einen 32-Bit-Launcher und 32-Bit-Client verwenden, um 32-Bit-Binärdateien zu fuzzen, und einen 64-Bit-Launcher und 64-Bit-Client für 64-Bit-Binärdateien!
Um die Instrumentierungsbibliothek zu kompilieren, müssen Sie die neueste Version von DynamoRIO verwenden. Der Quellcode der Instrumentierungsbibliothek befindet sich in dbi_clients_src im Hauptordner von Manul.
64-Bit Linux
cd dbi_clients_src
wget <DynamoRIO-x86_64-Linux-X.XX.XXXX-X.tar.gz> - Laden Sie das neueste DynamoRIO herunter
tar xvf DynamoRIO-x86_64-X.XX.XXXX-X.tar.gz
mkdir client_64
cd client_64
cmake ../dr_cov/ -DDynamoRIO_DIR=/home/max/manul/dbi_clients_src/DynamoRIO-x86_64-Linux-X.XX.XXXX-X.tar.gz/cmake
make
32-Bit Linux
cd dbi_clients_src
wget <DynamoRIO-i386-Linux-X.XX.XXXX-X.tar.gz> - Laden Sie das neueste DynamoRIO herunter
tar xvf DynamoRIO-x86_64-X.XX.XXXX-X.tar.gz
mkdir client_64
cd client_64
CFLAGS=-m32 CXXFLAGS=-m32 cmake ../dr_cov/ -DDynamoRIO_DIR=/home/max/manul/dbi_clients_src/DynamoRIO-i386-Linux-X.XX.XXXX-X.tar.gz/cmake
make
Unter Windows ist der einfachste Weg, die Bibliothek zu kompilieren, Visual Studio zu installieren (getestet mit Versionen 2017 & 2013), VS20XX Cross Tools Command Prompt zu starten und die folgenden Befehle auszuführen:
64-Bit Windows
cd dbi_clients_src
<Laden Sie die neueste Version von DynamoRIO herunter und extrahieren Sie sie>
mkdir client_64
cd client_64
cmake -G"Visual Studio 15 Win64" ..\dr_cov\ -DDynamoRIO_DIR=C:\Users\max\manul\dbi_clients_src\DynamoRIO-Windows-XXXX.XX.X.X\cmake
cmake --build . --config RelWithDebInfo (oder nur Debug, falls erforderlich)
32-Bit Windows
cd dbi_clients_src
<Laden Sie die neueste Version von DynamoRIO herunter und extrahieren Sie sie>
mkdir client_32
cd client_32
cmake -G"Visual Studio 15" ..\dr_cov\ -DDynamoRIO_DIR=C:\Users\max\manul\dbi_clients_src\DynamoRIO-Windows-XXXX.XX.X.X\cmake
cmake --build . --config RelWithDebInfo (oder nur Debug, falls erforderlich)
Manul unterstützte ursprünglich Intel PIN-unterstütztes abdeckungsgesteuertes Fuzzing, wird aber aufgrund geringer Leistung und hohem Wartungsaufwand nicht mehr unterstützt.
Die am häufigsten verwendeten Optionen können über die Befehlszeile bereitgestellt werden. Weitere Optionen werden über eine Konfigurationsdatei (manul.config) unterstützt.
Beispiel: python3 manul.py -i corpus -o out_dir -n 40 "target @@"
positionale Argumente:
target_binary Die auszuführende Ziel-Binärdatei und Optionen (vergessen Sie nicht, Anführungszeichen zu setzen, z.B. "target e @@").
optionale Argumente:
-h, --help Zeigt diese Hilfemeldung an und beendet sich.
-n NFUZZERS Anzahl paralleler Fuzzer
-s Führt dummes Fuzzing aus (keine Code-Instrumentierung)
-c CONFIG Pfad zur Konfigurationsdatei mit zusätzlichen Optionen (siehe Abschnitt Konfigurationsdatei-Optionen unten)
-r Vorherige Sitzung wiederherstellen
Erforderliche Parameter:
-i INPUT Pfad zum Verzeichnis mit dem initialen Korpus
-o OUTPUT Pfad zum Ausgabeverzeichnis
Manul wird mit einer standardmäßigen manul.config-Datei ausgeliefert, in der der Benutzer alle unterstützten Optionen und Anwendungsbeispiele finden kann. Optionen sollten im folgenden Format angegeben werden: Format: <optionsname> = <wert>. Das Symbol # kann verwendet werden, um eine Zeile zu ignorieren.
dict = /home/max/dictionaries/test.dict. Die AFL-Mutationsstrategie erlaubt es dem Benutzer, eine Liste benutzerdefinierter Tokens anzugeben, die an zufälligen Stellen in der gefuzten Datei eingefügt werden können. Manul unterstützt diese Funktionalität über diese Option (absolute Pfade bevorzugt).
mutator_weights=afl:7,radamsa:2,my_mutator:1. Mutator-Gewichte erlauben es dem Benutzer, Manul mitzuteilen, wie viele Mutationen pro 10 Ausführungen von einem bestimmten Fuzzer durchgeführt werden sollen. In diesem Beispiel wird der AFL-Mutator in 7/10 Mutationen ausgeführt, Radamsa in 2/10 und ein benutzerdefinierter my_mutator erhält 1/10. Wenn Sie einen bestimmten Mutator deaktivieren möchten, sollte das Gewicht auf 0 gesetzt werden (z.B. mutator_weights=afl:0,radamsa:1,my_mutator:9).
deterministic_seed = False|True. Durch die Angabe von True werden Radamsa-Mutationen deterministisch, sodass jeder Lauf von Manul zu denselben Ausgaben führt.
print_per_thread = False|True. Wenn diese Option aktiviert ist, gibt Manul eine Zusammenfassung für jeden ausgeführten Thread anstelle einer Gesamtzusammenfassung aus.
disable_volatile_bytes = False|True. Wenn diese Option aktiviert ist, setzt Manul keine flüchtigen Pfade auf die schwarze Liste.
forkserver_on = False|True. Aktivieren oder deaktivieren Sie AFL's Forkserver.
dbi = dynamorio|pin. Diese Option teilt Manul mit, welches DBI-Framework zur Instrumentierung des Ziels verwendet wird.
dbi_root = <pfad>. Diese Option teilt Manul mit, wo der Hauptlauncher des DBI-Frameworks zu finden ist.
dbi_client_root = <pfad>. Diese Option teilt Manul mit, wo der DBI-Client zur Durchführung der Instrumentierung zu finden ist.
dbi_client_libs = name_#1,name_#2|None. Diese Option kann verwendet werden, um eine Liste von Bibliotheken anzugeben, die zusammen mit dem Hauptziel instrumentiert werden sollen (z.B. wenn Sie eine ausführbare Datei haben, die die Zielbibliothek lädt, sowie mehrere andere, in denen Sie nach Fehlern suchen möchten).
dbi_persistence_mode = 0|1|2. Diese Option wird verwendet, um zwischen DBI-Persistenzmodi zu wählen. 0 - keine Persistenz, 1 - Standard-Persistenz (Funktions-Wrapping), 2 - noch nicht unterstützt.
Wenn dbi-persistence_mode = 1|2, sollten die folgenden Optionen angegeben werden:
dbi_target_module = <modulname>. Manul wird versuchen, die Zielfunktion in dem hier angegebenen Modul zu suchen.
dbi_target_method = <funktionsname>. Funktionsname, der für Persistenz gewrappt werden soll.
dbi_target_offset = <Offset der Funktion, z.B. 0x3198>. Funktions-Offset, der für Persistenz gewrappt werden soll. Diese Option kann anstelle von dbi_target_method verwendet werden, wenn keine Debugsymbole verfügbar sind.
dbi_fuzz_iterations = 500. Die Anzahl der Fuzz-Iterationen, die im Speicher ausgeführt werden, bevor das gesamte Programm neu startet. Sie können mit diesem Argument experimentieren, um den Wert zu finden, der am besten mit Ihrem Ziel funktioniert.
dbi_thread_coverage = False. Instrumentiert nur die Abdeckung von einem Thread, der die Zielfunktion ausgeführt hat (noch nicht unterstützt).
timeout = 10. Zeit, die gewartet wird, bevor das Ziel getötet und der nächste Testfall gesendet wird.
init_wait = 1. Diese Option kann verwendet werden, um ein Timeout einzurichten, das für die Initialisierung des Ziels erforderlich ist.
Die Optionen net_config_master und net_config_slave werden verwendet, um Manul-Instanzen über das Netzwerk zu verteilen. Sie müssen die folgenden 3 Schritte ausführen, um verteiltes Fuzzing durchzuführen.
IP:Port, auf denen Ihre Slaves ausgeführt werden.net_config_slave = 0.0.0.0:1337. Manul startet die Instanz und wartet auf eine eingehende Verbindung von der Master-Instanz auf Port 1337.net_config_master = dateiname.debug = False|True - Debug-Informationen ausgeben.
logging_enable = False|True - Debug-Informationen im Log speichern.
manul_logo = False|True - Manul-Logo am Anfang ausgeben.
no_stats = False|True - Statistiken speichern.
sync_freq = 10000. Ermöglicht dem Benutzer, die Synchronisationsfrequenz der Abdeckungs-Bitmap zu ändern. Diese Option teilt Manul mit, wie oft die Abdeckung zwischen parallelen Fuzzing-Instanzen synchronisiert werden soll. Ein niedrigerer Wert verringert die Leistung, erhöht aber die Koordination zwischen den Instanzen.
#custom_path = test_path - Diese Option ermöglicht es, den Testfall in einem benutzerdefinierten Ordner zu speichern (falls das Ziel ihn von einem vordefinierten Ort laden möchte).
cmd_fuzzing = True|False. Wenn diese Option aktiviert ist, stellt Manul die Eingabe über die Befehlszeile bereit, anstatt sie in einer Datei zu speichern.
user_signals = 6,2,1|None. Der Benutzer kann Manul mitteilen, welche Signale vom Ziel ignoriert werden sollen (nicht als Absturz betrachten).
target_ip_port = 127.0.0.1:7715|None - Wird verwendet, um Ziel-IP und -PORT anzugeben.
target_protocol = tcp|tcp - Wird verwendet, um das Protokoll zum Senden der Eingabe an das Ziel über das Netzwerk anzugeben.
net_sleep_between_cases = 0.0. Diese Option kann verwendet werden, um eine Verzögerung zwischen Testfällen zu definieren, die an das Ziel gesendet werden.
Derzeit ist Netzwerk-Fuzzing eine experimentelle Funktion (siehe Issues für weitere Details).
Ein benutzerdefinierter Mutator kann in den folgenden drei Schritten hinzugefügt werden: Schritt 1. Erstellen Sie eine Python-Datei (.py) und geben Sie ihr einen Namen (z.B. example_mutator.py)
Schritt 2. Erstellen Sie zwei Funktionen: def init(fuzzer_id) und def mutate(data). Siehe example_mutator für weitere Details. Manul ruft die init-Funktion während der Fuzzing-Initialisierung auf und mutate für jede Datei, die an das Ziel übergeben wird.
Schritt 3. Aktivieren Sie den Mutator, indem Sie seinen Namen mit mutator_weights in manul.config angeben. Z.B. mutator_weights=afl:2,radamsa:0,example_mutator:8.
HINWEIS: AFL- und Radamsa-Mutatoren sollten immer angegeben werden. Wenn Sie AFL und/oder Radamsa deaktivieren möchten, weisen Sie ihnen einfach das Gewicht 0 zu.
TBD
