
american fuzzy lop - ein sicherheitsorientierter Fuzzer
Ursprünglich entwickelt von Michal Zalewski [email protected].
Siehe QuickStartGuide.txt, wenn du keine Zeit hast, diese Datei zu lesen.
Fuzzing ist eine der leistungsfähigsten und bewährtesten Strategien zur Identifizierung von Sicherheitsproblemen in realer Software; es ist verantwortlich für die überwiegende Mehrheit der bisher gefundenen Fehler bei Remote-Codeausführung und Privilegieneskalation in sicherheitskritischer Software.
Leider ist Fuzzing auch relativ oberflächlich; blinde, zufällige Mutationen machen es sehr unwahrscheinlich, bestimmte Codepfade im getesteten Code zu erreichen, sodass einige Schwachstellen eindeutig außerhalb der Reichweite dieser Technik liegen.
Es gab zahlreiche Versuche, dieses Problem zu lösen. Einer der frühen Ansätze – von Tavis Ormandy entwickelt – ist die Korpus-Destillation. Die Methode stützt sich auf Abdeckungssignale, um aus einem massiven, hochwertigen Korpus von Kandidatendateien eine Teilmenge interessanter Seeds auszuwählen, und fuzzt diese anschließend mit traditionellen Mitteln. Der Ansatz funktioniert außergewöhnlich gut, erfordert jedoch, dass ein solcher Korpus leicht verfügbar ist. Darüber hinaus liefern Blockabdeckungsmessungen nur ein sehr vereinfachtes Verständnis des Programmzustands und sind auf lange Sicht weniger nützlich, um die Fuzzing-Bemühungen zu lenken.
Andere, ausgefeiltere Forschung hat sich auf Techniken wie Programmflussanalyse („concolic execution"), symbolische Ausführung oder statische Analyse konzentriert. Alle diese Methoden sind in experimentellen Umgebungen äußerst vielversprechend, leiden jedoch in der praktischen Anwendung tendenziell unter Zuverlässigkeits- und Leistungsproblemen – und bieten derzeit keine tragfähige Alternative zu „dummen" Fuzzing-Techniken.
American Fuzzy Lop ist ein Brute-Force-Fuzzer, gekoppelt mit einem äußerst einfachen, aber felsenfesten instrumentierungsgesteuerten genetischen Algorithmus. Er verwendet eine modifizierte Form der Kantenabdeckung, um mühelos subtile, lokale Änderungen im Kontrollfluss des Programms zu erfassen.
Vereinfacht ausgedrückt lässt sich der Gesamtalgorithmus wie folgt zusammenfassen:
Benutzerbereitgestellte anfängliche Testfälle in die Warteschlange laden,
Nächste Eingabedatei aus der Warteschlange nehmen,
Versuchen, den Testfall auf die kleinste Größe zu reduzieren, die das gemessene Verhalten des Programms nicht verändert,
Die Datei wiederholt mit einer ausgewogenen und gut recherchierten Vielfalt traditioneller Fuzzing-Strategien mutieren,
Wenn eine der erzeugten Mutationen zu einem neuen, durch die Instrumentierung aufgezeichneten Zustandsübergang führte, die mutierte Ausgabe als neuen Eintrag zur Warteschlange hinzufügen.
Weiter zu 2.
Die entdeckten Testfälle werden außerdem regelmäßig ausgedünnt, um solche zu eliminieren, die durch neuere Funde mit höherer Abdeckung überholt wurden; und sie durchlaufen mehrere weitere instrumentierungsgesteuerte Aufwandsminimierungsschritte.
Als Nebenergebnis des Fuzzing-Prozesses erstellt das Werkzeug ein kleines, in sich geschlossenes Korpus interessanter Testfälle. Diese sind äußerst nützlich, um andere arbeits- oder ressourcenintensive Testverfahren zu befüttern – zum Beispiel zum Belastungstesten von Browsern, Office-Anwendungen, Grafikpaketen oder Closed-Source-Werkzeugen.
Der Fuzzer ist gründlich getestet, um sofort eine Leistung zu liefern, die blindem Fuzzing oder reinen Abdeckungswerkzeugen weit überlegen ist.
Wenn Quellcode verfügbar ist, kann die Instrumentierung durch ein Begleitwerkzeug injiziert werden, das als direkter Ersatz für gcc oder clang in jedem Standard-Build-Prozess für Drittanbieter-Code fungiert.
Die Instrumentierung hat eine recht geringe Leistungsbeeinträchtigung; in Verbindung mit anderen von afl-fuzz implementierten Optimierungen können die meisten Programme so schnell oder sogar schneller gefuzzt werden, als es mit traditionellen Werkzeugen möglich wäre.
Der korrekte Weg, das Zielprogramm neu zu kompilieren, kann je nach den Besonderheiten des Build-Prozesses variieren, aber ein nahezu universeller Ansatz wäre:```shell $ CC=/path/to/afl/afl-gcc ./configure $ make clean all
Für C++-Programme solltest du auch `CXX=/path/to/afl/afl-g++` setzen.
Die Clang-Wrapper (`afl-clang` und `afl-clang++`) können auf dieselbe Weise verwendet werden;
Clang-Nutzer können optional auch einen leistungsfähigeren Instrumentierungsmodus nutzen,
wie in llvm_mode/README.llvm beschrieben.
Beim Testen von Bibliotheken musst du ein einfaches Programm finden oder schreiben, das
Daten von stdin oder aus einer Datei liest und sie an die getestete Bibliothek übergibt. In einem solchen
Fall ist es wichtig, diese ausführbare Datei gegen eine statische Version der
instrumentierten Bibliothek zu linken oder sicherzustellen, dass die richtige .so-Datei zur
Laufzeit geladen wird (normalerweise durch Setzen von `LD_LIBRARY_PATH`). Die einfachste Option ist ein statischer
Build, der normalerweise wie folgt möglich ist:```shell
$ CC=/path/to/afl/afl-gcc ./configure --disable-shared
Wenn Sie beim Aufruf von 'make' AFL_HARDEN=1 setzen, veranlasst das den CC-Wrapper,
automatisch Code-Härtungsoptionen zu aktivieren, die es erleichtern, einfache
Speicherfehler zu erkennen. Libdislocator, eine in AFL enthaltene Hilfsbibliothek (siehe
libdislocator/README.dislocator), kann ebenfalls dabei helfen, Heap-Korruptionsprobleme aufzudecken.
PS. ASAN-Benutzern wird empfohlen, die Datei notes_for_asan.txt auf wichtige Einschränkungen hin zu überprüfen.
Wenn der Quellcode NICHT verfügbar ist, bietet der Fuzzer experimentelle Unterstützung für schnelle, On-the-fly-Instrumentierung von Black-Box-Binärdateien. Dies wird erreicht mit einer Version von QEMU, die im weniger bekannten Modus "user space emulation" läuft.
QEMU ist ein von AFL unabhängiges Projekt, aber Sie können die Funktion bequem erstellen, indem Sie Folgendes tun:```shell $ cd qemu_mode $ ./build_qemu_support.sh
Weitere Hinweise und Anleitungen findest du in qemu_mode/README.qemu.
Der Modus ist etwa 2-5x langsamer als Compile-Time-Instrumentierung, eignet
sich weniger gut für die Parallelisierung und kann einige andere Eigenheiten
aufweisen.
## 5) Auswahl der ersten Testfälle
Um korrekt zu funktionieren, benötigt der Fuzzer eine oder mehrere Startdateien,
die ein gutes Beispiel der Eingabedaten enthalten, die von der Zielanwendung
normalerweise erwartet werden. Es gibt zwei Grundregeln:
- Halte die Dateien klein. Unter 1 kB ist ideal, wenn auch nicht zwingend
erforderlich. Eine Diskussion darüber, warum die Größe wichtig ist, findest
du in [perf_tips.txt](https://github.com/google/afl/blob/HEAD/docs/perf_tips.txt).
- Verwende mehrere Testfälle nur dann, wenn sie sich funktional voneinander
unterscheiden. Es hat keinen Sinn, fünfzig verschiedene Urlaubsfotos zu
verwenden, um eine Bildbibliothek zu fuzzen.
Viele gute Beispiele für Startdateien findest du im Unterverzeichnis testcases/,
das mit diesem Tool geliefert wird.
PS. Wenn ein großer Datenkorpus für das Screening verfügbar ist, möchtest du
vielleicht das Dienstprogramm afl-cmin verwenden, um eine Teilmenge funktional
unterschiedlicher Dateien zu identifizieren, die verschiedene Codepfade im
Zielbinary durchlaufen.
## 6) Fuzzing von Binaries
Der Fuzzing-Prozess selbst wird vom Dienstprogramm afl-fuzz durchgeführt. Dieses
Programm benötigt ein schreibgeschütztes Verzeichnis mit ersten Testfällen, einen
separaten Ort zum Speichern seiner Ergebnisse sowie einen Pfad zum zu testenden
Binary.
Für Zielbinaries, die Eingaben direkt von stdin akzeptieren, lautet die übliche
Syntax:```shell
$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]
Für Programme, die Eingaben aus einer Datei lesen, verwenden Sie '@@', um die Stelle in der Befehlszeile des Zielprogramms zu markieren, an der der Name der Eingabedatei platziert werden soll. Der Fuzzer ersetzt dies für Sie:```shell $ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@
Sie können auch die Option -f verwenden, um die mutierten Daten in eine bestimmte Datei schreiben zu lassen. Dies ist nützlich, wenn das Programm eine bestimmte Dateierweiterung oder Ähnliches erwartet.
Nicht instrumentierte Binärdateien können im QEMU-Modus (fügen Sie -Q in der Befehlszeile hinzu) oder in einem traditionellen Blind-Fuzzer-Modus (geben Sie -n an) gefuzzt werden.
Sie können -t und -m verwenden, um das Standard-Timeout und das Speicherlimit für den ausgeführten Prozess zu überschreiben; seltene Beispiele für Ziele, die diese Einstellungen möglicherweise benötigen, sind Compiler und Videodecoder.
Tipps zur Optimierung der Fuzzing-Leistung werden in [perf_tips.txt](https://github.com/google/afl/blob/HEAD/docs/perf_tips.txt) erörtert.
Beachten Sie, dass afl-fuzz mit einer Reihe von deterministischen Fuzzing-Schritten beginnt, die mehrere Tage dauern können, aber in der Regel saubere Testfälle hervorbringen. Wenn Sie schnelle & schmutzige Ergebnisse sofort wünschen – ähnlich wie bei zzuf und anderen traditionellen Fuzzern – fügen Sie die Option -d zur Befehlszeile hinzu.
## 7) Ausgabe interpretieren
Siehe die Datei [status_screen.txt](https://github.com/google/afl/blob/HEAD/docs/status_screen.txt) für Informationen zur Interpretation der angezeigten Statistiken und zur Überwachung des Prozesszustands. Konsultieren Sie diese Datei unbedingt, insbesondere wenn UI-Elemente rot hervorgehoben sind.
Der Fuzzing-Prozess läuft weiter, bis Sie Strg-C drücken. Mindestens sollten Sie dem Fuzzer erlauben, einen Queue-Zyklus abzuschließen, was je nach Ziel zwischen ein paar Stunden und etwa einer Woche dauern kann.
Innerhalb des Ausgabeverzeichnisses werden drei Unterverzeichnisse erstellt und in Echtzeit aktualisiert:
- queue/ - Testfälle für jeden charakteristischen Ausführungspfad sowie alle vom Benutzer angegebenen Startdateien. Dies ist das synthetisierte Korpus, das in Abschnitt 2 erwähnt wird.
Bevor Sie dieses Korpus für andere Zwecke verwenden, können Sie es mit dem Tool afl-cmin auf eine kleinere Größe verkleinern. Das Tool findet eine kleinere Teilmenge von Dateien, die eine gleichwertige Kantenabdeckung bieten.
- crashes/ - eindeutige Testfälle, die dazu führen, dass das getestete Programm ein fatales Signal empfängt (z. B. SIGSEGV, SIGILL, SIGABRT). Die Einträge werden nach dem empfangenen Signal gruppiert.
- hangs/ - eindeutige Testfälle, die dazu führen, dass das getestete Programm eine Zeitüberschreitung erleidet. Das Standard-Zeitlimit, bevor etwas als Hang eingestuft wird, ist der größere Wert von 1 Sekunde und dem Wert des Parameters -t.
Der Wert kann durch Setzen von AFL_HANG_TMOUT feinjustiert werden, aber das ist selten notwendig.
Crashes und Hangs gelten als „eindeutig", wenn die zugehörigen Ausführungspfade Zustandsübergänge beinhalten, die bei zuvor aufgezeichneten Fehlern nicht gesehen wurden. Wenn ein einzelner Fehler auf mehreren Wegen erreicht werden kann, gibt es zu Beginn des Prozesses eine gewisse Zählinflation, die jedoch schnell abklingen sollte.
Die Dateinamen für Crashes und Hangs sind mit übergeordneten, nicht fehlerhaften Queue-Einträgen korreliert. Dies sollte beim Debuggen helfen.
Wenn Sie einen von afl-fuzz gefundenen Crash nicht reproduzieren können, liegt die wahrscheinlichste Ursache darin, dass Sie nicht dasselbe Speicherlimit setzen wie das Tool. Versuchen Sie:```shell
$ LIMIT_MB=50
$ ( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... )
Ändern Sie LIMIT_MB so, dass es dem -m Parameter entspricht, der an afl-fuzz übergeben wird. Unter OpenBSD, ändern Sie außerdem -Sv in -Sd.
Jedes vorhandene Ausgabeverzeichnis kann auch verwendet werden, um abgebrochene Aufträge fortzusetzen; versuchen Sie:```shell $ ./afl-fuzz -i- -o existing_output_dir [...etc...]
Wenn gnuplot installiert ist, kannst du mit afl-plot auch hübsche Graphen für jede
aktive Fuzzing-Aufgabe erzeugen. Ein Beispiel dafür, wie das aussieht,
findest du unter [http://lcamtuf.coredump.cx/afl/plot/](http://lcamtuf.coredump.cx/afl/plot/).
## 8) Paralleles Fuzzing
Jede Instanz von afl-fuzz benötigt ungefähr einen Kern. Das bedeutet, dass auf
Mehrkernsystemen eine Parallelisierung notwendig ist, um die Hardware vollständig auszunutzen.
Tipps zum Fuzzing eines gemeinsamen Ziels auf mehreren Kernen oder mehreren vernetzten
Maschinen findest du in [parallel_fuzzing.txt](https://github.com/google/afl/blob/HEAD/docs/parallel_fuzzing.txt).
Der parallele Fuzzing-Modus bietet auch eine einfache Möglichkeit, AFL mit anderen
Fuzzern, symbolischen oder concolic Ausführungs-Engines usw. zu verbinden; siehe auch
den letzten Abschnitt von [parallel_fuzzing.txt](https://github.com/google/afl/blob/HEAD/docs/parallel_fuzzing.txt) für Tipps.
## 9) Fuzzer-Wörterbücher
Standardmäßig ist die Mutations-Engine von afl-fuzz für kompakte Datenformate optimiert -
etwa Bilder, Multimedia, komprimierte Daten, reguläre Ausdrücke oder Shell-Skripte.
Sie ist etwas weniger geeignet für Sprachen mit besonders ausführlichem und redundantem
Wortschatz - insbesondere HTML, SQL oder JavaScript.
Um den Aufwand zu vermeiden, syntaxbewusste Werkzeuge zu entwickeln, bietet afl-fuzz eine Möglichkeit,
den Fuzzing-Prozess mit einem optionalen Wörterbuch aus Sprachschlüsselwörtern, Magic Headern
oder anderen speziellen Tokens zu versorgen, die mit dem Ziel-Datentyp verbunden sind
-- und damit die zugrunde liegende Grammatik im laufenden Betrieb zu rekonstruieren:
[http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html](http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html)
Um diese Funktion zu nutzen, musst du zuerst ein Wörterbuch in einem der beiden
Formate erstellen, die in dictionaries/README.dictionaries beschrieben werden, und es dann
über die Option -x in der Befehlszeile an den Fuzzer übergeben.
(Auch einige gängige Wörterbücher sind in diesem Unterverzeichnis bereits enthalten.)
Es gibt keine Möglichkeit, strukturiertere Beschreibungen der zugrunde liegenden
Syntax bereitzustellen, aber der Fuzzer wird wahrscheinlich einen Teil davon allein anhand des
Instrumentierungs-Feedbacks herausfinden. Das funktioniert in der Praxis tatsächlich, zum Beispiel:
[http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html](http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html)
PS. Auch wenn kein explizites Wörterbuch angegeben wird, versucht afl-fuzz, vorhandene
Syntax-Tokens im Eingabekorpus zu extrahieren, indem es die Instrumentierung
während deterministischer Byte-Flips sehr genau beobachtet. Das funktioniert für einige Arten von
Parsern und Grammatiken, ist aber bei weitem nicht so gut wie der -x-Modus.
Wenn ein Wörterbuch wirklich schwer zu beschaffen ist, besteht eine weitere Möglichkeit darin, AFL
eine Weile laufen zu lassen und dann die Token-Capture-Bibliothek zu verwenden, die als
Begleitwerkzeug zu AFL mitgeliefert wird. Siehe dazu libtokencap/README.tokencap.
## 10) Crash-Triage
Die abdeckungsbasierte Gruppierung von Abstürzen erzeugt normalerweise einen kleinen Datensatz, der
schnell manuell oder mit einem sehr einfachen GDB- oder Valgrind-Skript gesichtet werden kann.
Jeder Absturz lässt sich außerdem auf seinen übergeordneten nicht abstürzenden Testfall in der
Warteschlange zurückführen, was die Diagnose von Fehlern erleichtert.
Allerdings ist es wichtig anzuerkennen, dass einige Fuzzing-Abstürze ohne viel
Debugging- und Codeanalyse-Aufwand nur schwer schnell auf ihre Ausnutzbarkeit bewertet werden können.
Um diese Aufgabe zu unterstützen, bietet afl-fuzz einen sehr besonderen
"Crash-Exploration"-Modus, der mit dem -C-Flag aktiviert wird.
In diesem Modus nimmt der Fuzzer einen oder mehrere abstürzende Testfälle als Eingabe
und nutzt seine feedbackgesteuerten Fuzzing-Strategien, um sehr schnell alle Codepfade
aufzulisten, die im Programm erreicht werden können, während es sich im
abstürzenden Zustand befindet.
Mutationen, die nicht zu einem Absturz führen, werden verworfen; ebenso alle Änderungen, die
den Ausführungspfad nicht beeinflussen.
Die Ausgabe ist ein kleines Korpus von Dateien, das sehr schnell untersucht werden kann, um zu sehen,
in welchem Ausmaß der Angreifer die Kontrolle über die fehlerhafte Adresse hat, oder ob es
möglich ist, eine anfängliche Out-of-Bounds-Read zu überwinden - und zu sehen, was sich
darunter befindet.
Oh, noch etwas: Für die Minimierung von Testfällen solltest du afl-tmin ausprobieren. Das Werkzeug
kann auf sehr einfache Weise bedient werden:```shell
$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...]
Das Tool funktioniert gleichermaßen mit abstürzenden und nicht abstürzenden Testfällen. Im Absturzmodus akzeptiert es bereitwillig instrumentierte und nicht instrumentierte Binaries. Im Nicht-Absturzmodus verlässt sich der Minimizer auf die Standard-AFL-Instrumentierung, um die Datei zu vereinfachen, ohne den Ausführungspfad zu verändern.
Der Minimizer akzeptiert die Syntax -m, -t, -f und @@ in einer Weise, die mit afl-fuzz kompatibel ist.
Eine weitere neue Ergänzung zu AFL ist das Tool afl-analyze. Es nimmt eine Eingabedatei, versucht, Bytes sequenziell zu kippen, und beobachtet das Verhalten des getesteten Programms. Anschließend farbcodiert es die Eingabe basierend darauf, welche Abschnitte kritisch erscheinen und welche nicht; auch wenn es nicht wasserdicht ist, kann es oft schnelle Einblicke in komplexe Dateiformate bieten. Weitere Informationen zu seiner Funktionsweise finden Sie gegen Ende der technical_details.txt.
Fuzzing ist eine wunderbare und untergenutzte Technik, um auch nicht abstürzende Design- und Implementierungsfehler zu entdecken. Eine ganze Reihe interessanter Bugs wurde gefunden, indem man die Zielprogramme so modifizierte, dass sie abort() aufrufen, wenn zum Beispiel:
Zwei Bignum-Bibliotheken unterschiedliche Ausgaben erzeugen, wenn sie dieselbe fuzzer-generierte Eingabe erhalten,
Eine Bildbibliothek unterschiedliche Ausgaben erzeugt, wenn sie gebeten wird, dasselbe Eingabebild mehrmals hintereinander zu dekodieren,
Eine Serialisierungs- / Deserialisierungsbibliothek keine stabilen Ausgaben erzeugt, wenn sie fuzzer-gelieferte Daten iterativ serialisiert und deserialisiert,
Eine Kompressionsbibliothek eine Ausgabe erzeugt, die inkonsistent mit der Eingabedatei ist, wenn sie gebeten wird, einen bestimmten Blob zu komprimieren und dann zu dekomprimieren.
Die Implementierung dieser oder ähnlicher Plausibilitätsprüfungen dauert normalerweise nur sehr wenig Zeit;
wenn Sie der Maintainer eines bestimmten Pakets sind, können Sie diesen Code
mit #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION (ein Flag, das auch
mit libfuzzer geteilt wird) oder #ifdef __AFL_COMPILER (dieses ist nur für AFL) konditional machen.
Bitte denken Sie daran, dass Fuzzing, ähnlich wie viele andere rechenintensive Aufgaben, Ihre Hardware und das Betriebssystem belasten kann. Insbesondere:
Ihre CPU wird heiß laufen und benötigt eine angemessene Kühlung. In den meisten Fällen wird die CPU-Geschwindigkeit automatisch gedrosselt, wenn die Kühlung unzureichend ist oder nicht mehr richtig funktioniert. Allerdings ist es, besonders beim Fuzzing auf weniger geeigneter Hardware (Laptops, Smartphones usw.), nicht gänzlich unmöglich, dass etwas durchbrennt.
Zielprogramme können unregelmäßig Gigabytes an Speicher verbrauchen oder die Festplatte mit Junk-Dateien füllen. AFL versucht, grundlegende Speichergrenzen durchzusetzen, kann aber nicht jedes mögliche Missgeschick verhindern. Die Quintessenz ist, dass Sie nicht auf Systemen fuzzen sollten, auf denen die Aussicht auf Datenverlust kein akzeptables Risiko darstellt.
Fuzzing beinhaltet Milliarden von Lese- und Schreibvorgängen auf dem Dateisystem. Auf modernen Systemen werden diese normalerweise stark gecacht, was zu einer ziemlich moderaten "physischen" E/A führt – aber es gibt viele Faktoren, die diese Gleichung verändern können. Es liegt in Ihrer Verantwortung, auf mögliche Probleme zu achten; bei sehr starker E/A kann die Lebensdauer vieler HDDs und SSDs reduziert werden.
Eine gute Möglichkeit, die Datenträger-E/A unter Linux zu überwachen, ist der Befehl 'iostat':```shell $ iostat -d 3 -x -k [...optional disk ID...]
## 13) Bekannte Einschränkungen & Verbesserungsbereiche
Hier sind einige der wichtigsten Warnhinweise für AFL:
- AFL erkennt Fehler, indem es prüft, ob der erste erzeugte Prozess stirbt,
aufgrund eines Signals (SIGSEGV, SIGABRT, etc.). Programme, die benutzerdefinierte
Handler für diese Signale installieren, müssen den relevanten Code auskommentieren. Im gleichen
Sinne können Fehler in Kindprozessen, die vom getesteten Ziel erzeugt werden, der
Erkennung entgehen, es sei denn, Sie fügen manuell Code hinzu, um das abzufangen.
- Wie bei jedem anderen Brute-Force-Werkzeug bietet der Fuzzer nur begrenzte Abdeckung, wenn
Verschlüsselung, Prüfsummen, kryptografische Signaturen oder Komprimierung verwendet werden, um
das tatsächlich zu testende Datenformat vollständig zu umhüllen.
Um dies zu umgehen, können Sie die entsprechenden Prüfungen auskommentieren (siehe
experimental/libpng_no_checksum/ zur Inspiration); falls das nicht möglich ist,
können Sie auch einen Postprozessor schreiben, wie in
experimental/post_library/ erläutert.
- Es gibt einige unglückliche Kompromisse bei ASAN und 64-Bit-Binaries. Dies
liegt nicht an einem spezifischen Fehler von afl-fuzz; siehe [notes_for_asan.txt](https://github.com/google/afl/blob/HEAD/docs/notes_for_asan.txt)
für Tipps.
- Es gibt keine direkte Unterstützung zum Fuzzen von Netzwerkdiensten, Hintergrund-
Daemons oder interaktiven Anwendungen, die UI-Interaktion erfordern. Möglicherweise
müssen Sie einfache Codeänderungen vornehmen, damit sie sich auf traditionellere
Weise verhalten. Preeny bietet möglicherweise auch eine relativ einfache Option – siehe:
https://github.com/zardus/preeny
Einige nützliche Tipps zum Anpassen netzwerkbasierter Dienste finden Sie auch unter:
https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop
- AFL gibt keine menschenlesbaren Abdeckungsdaten aus. Wenn Sie die Abdeckung überwachen
möchten, verwenden Sie afl-cov von Michael Rash: https://github.com/mrash/afl-cov
- Gelegentlich erheben sich empfindungsfähige Maschinen gegen ihre Schöpfer. Wenn Ihnen
das passiert, konsultieren Sie bitte http://lcamtuf.coredump.cx/prep/.
Darüber hinaus finden Sie plattformspezifische Hinweise in INSTALL.
## 14) Besonderer Dank
Viele der Verbesserungen an afl-fuzz wären ohne Feedback,
Fehlerberichte oder Patches von Folgenden nicht möglich:```
Jann Horn Hanno Boeck
Felix Groebert Jakub Wilk
Richard W. M. Jones Alexander Cherepanov
Tom Ritter Hovik Manucharyan
Sebastian Roschke Eberhard Mattes
Padraig Brady Ben Laurie
@dronesec Luca Barbato
Tobias Ospelt Thomas Jarosch
Martin Carpenter Mudge Zatko
Joe Zbiciak Ryan Govostes
Michael Rash William Robinet
Jonathan Gray Filipe Cabecinhas
Nico Weber Jodie Cunningham
Andrew Griffiths Parker Thompson
Jonathan Neuschfer Tyler Nighswander
Ben Nagy Samir Aguiar
Aidan Thornton Aleksandar Nikolich
Sam Hakim Laszlo Szekeres
David A. Wheeler Turo Lamminen
Andreas Stieger Richard Godbee
Louis Dassy teor2345
Alex Moneger Dmitry Vyukov
Keegan McAllister Kostya Serebryany
Richo Healey Martijn Bogaard
rc0r Jonathan Foote
Christian Holler Dominique Pelle
Jacek Wielemborek Leo Barnes
Jeremy Barnes Jeff Trull
Guillaume Endignoux ilovezfs
Daniel Godas-Lopez Franjo Ivancic
Austin Seipp Daniel Komaromy
Daniel Binderman Jonathan Metzman
Vegard Nossum Jan Kneschke
Kurt Roeckx Marcel Bohme
Van-Thuan Pham Abhik Roychoudhury
Joshua J. Drake Toby Hutton
Rene Freingruber Sergey Davidoff
Sami Liedes Craig Young
Andrzej Jackowski Daniel Hodson
Vielen Dank!
Fragen? Anliegen? Fehlermeldungen? Bitte nutze GitHub.
Es gibt auch eine Mailingliste für das Projekt; um beizutreten, sende eine E-Mail an [email protected]. Oder, falls du zuerst die Archive durchsuchen möchtest, versuche: https://groups.google.com/group/afl-users.