
A Not So Very Intelligent Fuzzer: Ein fortschrittliches Fuzzing-Framework zur Erkennung von Schwachstellen in C/C++-Code.
Ein nicht sonderlich intelligenter Fuzzer
Marshall Whittaker
oxagast
Mit der Komplexität eines Systems steigt auch das Potenzial für Probleme in diesem System.
--Whittakers Gesetz
Kompilierungsabhängigkeiten:
automake autoconf-archive zlib1g-dev g++ gcc (and libgtk2.0-dev if you want GTK support)
Kompilierung:
Linux:
$ aclocal && autoconf && automake -a && ./configure && make && make check
Oder, falls du mit dem Syscall-Fuzzer spielen möchtest:
$ aclocal && autoconf && automake -a && ./configure --enable-syscalls && make && make check
Falls du das GTK-Frontend deaktivieren möchtest, kannst du Folgendes tun:
$ aclocal && autoconf && automake -a && ./configure --disable-gtk && make && make check
FreeBSD
Angenommen, du hast g++ aus den Ports installiert (wie für C++11 benötigt):
$ aclocal && autoconf && automake -a && ./configure && make && make check
OpenBSD:
Angenommen, du hast g++ aus den Ports installiert (wie für C++11 benötigt):
$ CXX=$(find / -name 'eg++' 2>/dev/null | grep ports | head -n 1) AUTOCONF_VERSION=2.69 AUTOMAKE_VERSION=1.15 autoreconf -fmi
Windows:
Windows-Binärdateien sind nun dafür ausgelegt, mit MinGW-W64 kompiliert zu werden (da wir Threading verwenden, lade eine Version von MinGW-W64 g++ mit seh herunter). Du kannst versuchen, es nach der Installation von MinGW-W64 g++ mit seh (nur) zu kompilieren, indem du auf das enthaltene Skript make_win.bat klickst. Wenn das fehlschlägt, liegt es wahrscheinlich an der Umgebung, also versuche Folgendes.
(Gehe zu dem Ort, an dem du MinGW-W64 installiert hast, und klicke auf mingw-64.bat)
windres metadata.rc -O coff -o metadata.res
g++.exe src/common.cpp src/bin2hex.cpp src/popen2.cpp src/main.cpp src/help.cpp src/match_fault.cpp src/sys_string.cpp src/man_read.cpp src/randomizer.cpp src/trash.cpp src/log.cpp metadata.res src/version.h -I./ -I./include -std=c++11 -lstdc++ -lpthread -O2 -o ansvif.exe -static -static-libgcc -static-libstdc++
gcc src/win/printf.c -o printf.exe
Hinweis: Externe .dll-Dateien von Cygwin werden nicht mehr benötigt, da wir jetzt mit g++ von MinGW kompilieren. In Windows 7 ist Powershell v2 standardmäßig installiert, dieses Programm benötigt jedoch mindestens Powershell v5. Windows 10 enthält Powershell v5. Du kannst auf der Microsoft-Website das Windows Management Framework herunterladen (das neuere Versionen von Powershell enthält):
https://www.microsoft.com/en-us/download/details.aspx?id=50395
Testen:
Wenn du den Beispielcode ausprobieren möchtest, kannst du faulty.c mit folgendem Befehl kompilieren:
$ gcc faulty.c -o faulty
Du kannst auch einfach make check ausführen.
Verwendung:
Wichtiger Hinweis: Windows-Benutzer müssen ansvif.exe von Powershell aus ausführen, damit es funktioniert!
$ ./find_suid /usr/bin/ /bin/ /sbin/
$ ./ansvif -[tm] [template/manpage] -c /path/to/executable -b buffersize
Beispiele:
Linux/BSD:
$ ulimit -c unlimited
$ ./ansvif -m mount -c /bin/mount -e examples/mount_e.txt -x examples/mount_o.txt\
-f 8 -b 2048
$ ./ansvif -t examples/blank.txt -F tmp/tmphtml -x examples/htmltags.txt -c /usr/bin/iceweasel -b\
128 -A "file:///home/username/src/ansvif/tmp/tmphtml" -f 2 -n -R "sleep 3 && killall\
iceweasel" -S ">"
$ cat examples/linux_syscalls_implemented.list | xargs -P \
`cat examples/linux_syscalls_implemented.list | wc -l` -I {calls} ./ansvif -t examples/space.txt \
-B "{calls} " -c ./syscalls -o syscall_crash -f 1 -z -d -b 16
Windows:
PS C:\ansvif\bin\ansvif_win> .\ansvif -t ..\..\examples\space -F ..\..\tmp\tmphtml -x `
..\..\examples\htmltags -c `
'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' `
-b 128 -A "file:///C:\\Users\marsh\OneDrive\Documents\Code\ansvif\tmp\tmphtml" `
-f 2 -n -S ">" -R "sleep 2 ; Stop-Process -Name chrome"
Optionen:
ansvif
-t Diese Datei sollte zeilenweise Befehlsargumente enthalten, wie in der Beispieldatei gezeigt.
-e Diese Datei sollte zeilenweise Umgebungsvariablen enthalten, wie in der Beispieldatei
gezeigt. Du kannst diese normalerweise erhalten, indem du so etwas tust:
$ strings /bin/mount | perl -ne 'print if /[A-Z]=$/' > mount_envs
-c Gibt den Befehlspfad an.
-p Gibt die Position der Manpage an (als Ganzzahl, normalerweise 1 oder 8)
-m Gibt die Manpage des Befehls an.
-D Zeigt an, was in der Manpage gefunden wurde.
-f Anzahl der zu verwendenden Threads. Standard ist 2.
-b Gibt die Puffergröße für das Fuzzing an. 256-2048 ist normalerweise ausreichend.
-r Verwendet nur zufällige Mülldaten.
-o Schreibt die Ausgabe in eine Logdatei.
-z Randomisiert die Puffergröße von 1 bis zu dem mit -b angegebenen Wert.
-x Anderer Kram, der eingefügt werden soll. Benutzernamen und Ähnliches können hier hinzugefügt werden.
-S Trennzeichen zwischen Optionen.
-s Spezifikation ausgelassener Zeichen. Standardmäßig sind <>\\n |&\[]\()\{}:; und ein Zeilenumbruch ist obligatorisch.
-T Timeout für Threads.
-W Timeout für Threads.
-L Nicht privilegierter Benutzer, als der ausgeführt werden soll, wenn root.
-A Fügt das danach Kommende immer nach dem auszuführenden Befehl ein.
-B Fügt das danach Kommende immer vor dem auszuführenden Befehl ein.
-F Datei, die in das Programm eingespeist wird, in die -x zusammen mit normalen Fuzzing-Daten eingefügt werden.
-n Verwendet niemals zufällige Daten im Fuzz.
-R Führt diesen Befehl nach jedem Fuzz aus.
-C Ein nicht standardmäßiger Fehlercode, der erkannt werden soll.
-V Verwendet Valgrind, falls installiert.
-1 Versucht, es einmal zum Fehler zu bringen. Wenn das nicht passiert, wird Fehlercode 64 ausgegeben. Nützlich für Skripte.
-P Verwendet %, um Binärdaten im Fuzz darzustellen.
-M Maximale Anzahl von Argumenten, die im Fuzz verwendet werden sollen.
-y Kurzform für -b 0 und normalerweise nur in Verbindung mit -A oder -B nützlich.
-K Fuzzt weiter nach einem Absturz des Ziels.
-E Ein Befehl, der vor dem gefuzzen Programm ausgeführt wird.
-0 Keine NULL-Zeichen im Fuzz.
-N Kurzform für -R "pkill prog".
-v Ausführlich.
-d Debug-Daten.
-h Zeigt die Hilfeseite an.
-i Zeigt Versionsinformationen an.
ansvif_gtk
-l Kurzform für -p ./ansvif
-p Der Speicherort der ansvif-Binärdatei
Empfehlungen: Es wird empfohlen, dass du bei langen Fuzzing-Durchläufen oder Datei-Fuzzing, wenn möglich, die Dateien (einschließlich der zu fuzzenden Binärdatei, falls möglich) im Arbeitsspeicher ablegst. Das bedeutet, du legst sie an einem Ort wie /var/run/shm ab, wo der Festplattenzugriff minimal ist und das Fuzzing etwas schneller läuft, insbesondere bei großen Dateien. Sei jedoch gewarnt: Du verlierst deine gefuzzen Dateien, wenn sie in shm liegen und du das System neu startest!
FÜHRE DIESEN CODE NICHT IN EINER PRODUKTIONSUMGEBUNG AUS! Wenn du versuchst, die Ausgabe von faulty.c auf suid(0) zu setzen, dann tue dies BITTE in einer virtuellen Maschine oder zumindest auf einem Rechner, der dir nicht wichtig ist. Ansonsten: Spiele einfach herum und habe Spaß!
Hinweise:
Windows-Benutzer müssen ansvif von Powershell aus ausführen. Der Linux- und Windows-Code sollte relativ stabil sein. Syscall-Fuzzing unter Linux befindet sich in intensiver Entwicklung.
Danke
Dank an dll999 für Ideen zum Syscall-Fuzzing. Dank an moo von #2600 im 2600net für ein paar Empfehlungen zum Wiki-Beitrag. Dank an weiß Gott wie viele Leute auf IRC und StackOverflow. Dank an DarkSt0rm für das Beheben eines Fehlers im Makefile.