Der Autor wählte die Electronic Frontier Foundation Inc, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten.
Sicherheitsbedrohungen werden immer ausgefeilter, sodass Entwickler und Systemadministratoren bei der Verteidigung und dem Testen der Sicherheit ihrer Anwendungen einen proaktiven Ansatz verfolgen müssen.
Eine gängige Methode zum Testen der Sicherheit von Client-Anwendungen oder Netzwerkdiensten ist das Fuzzing, bei dem wiederholt ungültige oder fehlerhafte Daten an die Anwendung gesendet und deren Antwort analysiert wird. Dies ist nützlich zum Testen, wie widerstandsfähig und robust die Anwendung gegenüber unerwarteten Eingaben ist, zu denen beschädigte Daten oder tatsächliche Angriffe gehören können.
Radamsa ist ein Open-Source-Fuzzing-Werkzeug, das Testfälle auf der Grundlage von benutzerdefinierten Eingabedaten generieren kann. Radamsa ist vollständig skriptfähig und hat bisher erfolgreich Schwachstellen in realen Anwendungen, wie z. B. Gzip, gefunden.
In diesem Tutorial werden Sie Radamsa installieren und verwenden, um Fuzz-Tests von Befehlszeilen- und netzwerkbasierten Anwendungen mit Ihren eigenen Testfällen durchzuführen.
Warnung: Radamsa ist ein Penetrationstesttool, mit dem Sie möglicherweise Schwachstellen oder Schwächen in bestimmten Systemen oder Anwendungen identifizieren können. Sie dürfen die mit Radamsa gefundenen Schwachstellen nicht für fahrlässiges Verhalten, Schädigung oder böswillige Ausnutzung verwenden. Schwachstellen sollten dem Betreuer der betroffenen Anwendung auf ethische Weise gemeldet und nicht ohne ausdrückliche Genehmigung öffentlich bekannt gegeben werden.
Bevor Sie diesen Leitfaden beginnen, benötigen Sie Folgendes:
Warnung: Radamsa kann dazu führen, dass Anwendungen oder Systeme instabil laufen oder abstürzen. Führen Sie Radamsa daher nur in einer Umgebung aus, in der Sie darauf vorbereitet sind, z. B. auf einem dedizierten Server. Bitte stellen Sie auch sicher, dass Sie die ausdrückliche schriftliche Genehmigung des Eigentümers eines Systems haben, bevor Sie Fuzz-Tests gegen dieses System durchführen.
Sobald Sie diese zur Verfügung haben, melden Sie sich zunächst als Benutzer ohne Rootberechtigung auf Ihrem Server an.
Zuerst werden Sie Radamsa herunterladen und kompilieren, um es auf Ihrem System zu verwenden. Der Radamsa-Quellcode ist im offiziellen Repository von GitLab verfügbar.
Beginnen Sie damit, den lokalen Paketindex zu aktualisieren, um alle neuen Änderungen im Upstream zu berücksichtigen:
- sudo apt update
Installieren Sie dann die Pakete gcc
, git
, make
und wget
, die zum Kompilieren des Quellcodes in eine ausführbare Binärdatei benötigt werden:
- sudo apt install gcc git make wget
Nach der Bestätigung der Installation lädt apt
die angegebenen Pakete und alle erforderlichen Abhängigkeiten herunter und installiert sie.
Als Nächstes laden Sie eine Kopie des Quellcodes für Radamsa herunter, indem Sie ihn aus dem Repository, das auf GitLab gehostet wird, klonen:
- git clone https://gitlab.com/akihe/radamsa.git
Dadurch wird ein Verzeichnis namens radamsa
erstellt, das den Quellcode für die Anwendung enthält. Wechseln Sie in das Verzeichnis, um mit der Kompilierung des Codes zu beginnen:
- cd radamsa
Als Nächstes können Sie den Kompilierungsprozess mit make
starten:
- make
Schließlich können Sie die kompilierte Radamsa-Binärdatei in Ihren $PATH
installieren:
- sudo make install
Sobald dies abgeschlossen ist, können Sie die installierte Version überprüfen, um sicherzustellen, dass alles funktioniert:
- radamsa --version
Ihre Ausgabe wird ähnlich wie die folgende aussehen:
OutputRadamsa 0.6
Wenn Sie einen Fehler radamsa: command not found
sehen, überprüfen Sie noch einmal, ob alle erforderlichen Abhängigkeiten installiert wurden und ob es beim Kompilieren keine Fehler gab.
Nachdem Sie nun Radamsa installiert haben, können Sie damit beginnen, einige Beispieltestfälle zu generieren, um zu verstehen, wie Radamsa funktioniert und wofür es verwendet werden kann.
Nachdem Radamsa jetzt installiert wurde, können Sie damit einige Fuzzing-Testfälle generieren.
Ein Testfall ist ein Datenteil, der als Eingabe für das zu testende Programm verwendet wird. Wenn Sie beispielsweise einen Fuzz-Test für ein Archivierungsprogramm wie Gzip durchführen, kann ein Testfall ein Dateiarchiv sein, das Sie zu dekomprimieren versuchen.
Anmerkung: Radamsa manipuliert Eingabedaten auf eine Vielzahl unerwarteter Arten, einschließlich extremer Wiederholungen, Bit-Flips, Einfügen von Steuerzeichen und so weiter. Dies kann dazu führen, dass Ihre Terminal-Sitzung abbricht oder instabil wird. Seien Sie sich dessen bewusst, bevor Sie fortfahren.
Geben Sie zunächst ein einfaches Textstück an Radamsa weiter, um zu sehen, was passiert:
- echo "Hello, world!" | radamsa
Dadurch werden die eingegebenen Daten manipuliert (oder gefuzzt) und ein Testfall ausgegeben, wie beispielsweise:
OutputHello,, world!
In diesem Fall hat Radamsa ein zusätzliches Komma zwischen Hello
und world
eingefügt. Dies mag nicht wie eine wesentliche Änderung erscheinen, aber in einigen Anwendungen kann dies dazu führen, dass die Daten falsch interpretiert werden.
Versuchen wir es noch einmal, indem wir den gleichen Befehl ausführen. Sie werden eine andere Ausgabe sehen:
OutputHello, '''''''wor'd!
Dieses Mal wurden mehrere einfache Anführungszeichen ('
) in die Zeichenfolge eingefügt, darunter eines, das das l
in world
überschrieb. Dieser spezielle Testfall führt mit größerer Wahrscheinlichkeit zu Problemen für eine Anwendung, da einfache/doppelte Anführungszeichen oft verwendet werden, um verschiedene Datenteile in einer Liste zu trennen.
Versuchen wir es noch einmal:
OutputHello, $+$PATH\u0000`xcalc`world!
In diesem Fall fügte Radamsa eine Shell-Injektionszeichenfolge ein, die zum Testen auf Befehlsinjektions-Schwachstellen in der zu testenden Anwendung nützlich sein wird.
Sie haben Radamsa dazu verwendet, eine Eingabezeichenfolge zu fuzzen und eine Reihe von Testfällen zu erstellen. Als Nächstes werden Sie Radamsa zum Fuzzen einer Befehlszeilenanwendung verwenden.
In diesem Schritt werden Sie Radamsa verwenden, um eine Befehlszeilenanwendung zu fuzzen und über alle auftretenden Abstürze zu berichten.
Die genaue Technik für das Fuzzing jedes Programms variiert erheblich und verschiedene Methoden werden für verschiedene Programme am effektivsten sein. In diesem Tutorial werden wir jedoch das Beispiel von jq
verwenden, das ein Befehlszeilenprogramm zur Verarbeitung von JSON-Daten ist.
Sie können jedes andere ähnliche Programm verwenden, solange es dem allgemeinen Prinzip folgt, eine Form von strukturierten oder unstrukturierten Daten zu nehmen, etwas damit zu tun und dann ein Ergebnis auszugeben. Dieses Beispiel würde zum Beispiel auch mit Gzip, Grep, bc, tr usw. funktionieren.
Wenn Sie jq
nicht bereits installiert haben, können Sie es mit apt
installieren:
- sudo apt install jq
jq
wird nun installiert.
Um mit dem Fuzzing zu beginnen, erstellen Sie eine JSON-Beispieldatei, die Sie als Eingabe für Radamsa verwenden:
- nano test.json
Fügen Sie dann die folgenden JSON-Beispieldaten in die Datei ein:
{
"test": "test",
"array": [
"item1: foo",
"item2: bar"
]
}
Sie können diese Datei mit jq
parsen, wenn Sie überprüfen wollen, ob die JSON-Syntax gültig ist:
- jq . test.json
Wenn die JSON gültig ist, wird jq
die Datei ausgeben. Andernfalls wird ein Fehler ausgegeben, mit dem Sie die Syntax bei Bedarf korrigieren können.
Als nächstes fuzzen Sie die JSON-Testdatei mit Radamsa und übergeben diese dann an jq
. Dadurch liest jq
den gefuzzten/manipulierten Testfall und nicht die ursprünglich gültigen JSON-Daten:
- radamsa test.json | jq
Wenn Radamsa die JSON-Datei auf eine Art und Weise fuzzt, dass sie syntaktisch noch gültig sind, gibt jq
die Daten aus, jedoch mit den Änderungen, die Radamsa daran vorgenommen hat.
Wenn Radamsa bewirkt, dass die JSON-Daten ungültig werden, zeigt jq
alternativ einen entsprechenden Fehler an. Beispiel:
Outputparse error: Expected separator between values at line 5, column 16
Das alternative Ergebnis wäre, dass jq
nicht in der Lage ist, die gefuzzten Daten korrekt zu verarbeiten, was zu einem Absturz oder Fehlverhalten führt. Genau das ist es, was Sie beim Fuzzing wirklich suchen, da dies auf eine Sicherheitsschwachstelle wie einen Pufferüberlauf oder eine Befehlsinjektion hindeuten könnte.
Um effizienter auf solche Schwachstellen zu testen, kann ein Bash-Skript verwendet werden, um den Fuzzing-Prozess zu automatisieren, einschließlich der Generierung von Testfällen, der Übergabe an das Zielprogramm und der Erfassung aller relevanten Ausgaben.
Erstellen Sie eine Datei namens jq-fuzz.sh
:
- nano jq-fuzz.sh
Der genaue Inhalt des Skripts hängt von der Art des Programms, das Sie fuzzen, und den Eingabedaten ab, aber im Fall von jq
und anderen ähnlichen Programmen reicht das folgende Skript aus.
Kopieren Sie das Skript in Ihre jq-fuzz.sh
-Datei:
#!/bin/bash
while true; do
radamsa test.json > input.txt
jq . input.txt > /dev/null 2>&1
if [ $? -gt 127 ]; then
cp input.txt crash-`date +s%.%N`.txt
echo "Crash found!"
fi
done
Dieses Skript enthält ein while
, um den Inhalt in einer Schleife zu wiederholen. Bei jedem Durchlaufen der Skript-Schleife generiert Radamsa einen Testfall auf der Basis von test.json
und speichert ihn in input.txt
.
Der input.txt
-Testfall wird dann durch jq
ausgeführt, wobei alle Standard- und Fehlerausgaben zu /dev/null
umgeleitet werden, um zu vermeiden, dass der Terminal-Bildschirm überfüllt wird.
Schließlich wird der Exit-Wert von jq
überprüft. Wenn der Exit-Wert größer als 127
ist, was auf einen fatalen Abbruch (einen Absturz) hindeutet, werden die Eingabedaten zur späteren Überprüfung in einer Datei mit dem Namen crash-
gespeichert – gefolgt vom aktuellen Datum in Unix-Sekunden und -Nanosekunden.
Markieren Sie das Skript als ausführbar und führen Sie es aus, um mit dem automatischen Fuzz-Test jq
zu beginnen:
- chmod +x jq-fuzz.sh
- ./jq-fuzz.sh
Um das Skript zu beenden können Sie jederzeit STRG+C
drücken. Sie können dann überprüfen, ob Abstürze gefunden wurden, indem Sie mit ls
eine Verzeichnisliste mit den erzeugten Absturzdateien anzeigen.
Vielleicht möchten Sie Ihre JSON-Eingabedaten verbessern, da die Verwendung einer komplexeren Eingabedatei wahrscheinlich die Qualität Ihrer Fuzzing-Ergebnisse verbessert. Vermeiden Sie die Verwendung einer großen Datei oder einer Datei, die viele sich wiederholende Daten enthält – eine ideale Eingabedatei ist eine Datei, die klein ist, aber dennoch so viele „komplexe“ Elemente wie möglich enthält. Eine gute Eingabedatei enthält beispielsweise Datenproben, die in allen Formaten gespeichert sind, einschließlich Zeichenfolgen, Ganzzahlen, Boolesche, Listen und Objekte, sowie, wenn möglich, verschachtelte Daten.
Sie haben Radamsa zum Fuzzen einer Befehlszeilenanwendung verwendet. Als Nächstes werden Sie Radamsa zum Fuzzen von Anfragen an Netzwerkdienste verwenden.
Radamsa kann auch zum Fuzzen von Netzwerkdiensten verwendet werden, wobei es entweder als Netzwerk-Client oder als Server fungiert. In diesem Schritt verwenden Sie Radamsa zum Fuzzen eines Netzwerkdienstes, wobei Radamsa als Client fungiert.
Der Zweck des Fuzzings von Netzwerkdiensten besteht darin, zu testen, wie belastbar ein bestimmter Netzwerkdienst gegenüber Clients ist, die ihm fehlerhafte und/oder bösartige Daten senden. Viele Netzwerkdienste wie Web- oder DNS-Server sind in der Regel dem Internet ausgesetzt, was bedeutet, dass sie ein häufiges Ziel für Angreifer sind. Ein Netzwerkdienst, der nicht ausreichend widerstandsfähig gegen den Empfang fehlerhafter Daten ist, kann abstürzen oder – schlimmer noch – in einem offenen Zustand ausfallen, sodass Angreifer sensible Daten wie Verschlüsselungsschlüssel oder Benutzerdaten lesen können.
Die spezifische Technik zum Fuzzing von Netzwerkdiensten variiert je nach dem betreffenden Netzwerkdienst enorm. In diesem Beispiel werden wir jedoch Radamsa zum Fuzzing eines einfachen Webservers verwenden, der statische HTML-Inhalte anbietet.
Zuerst müssen Sie den Webserver für die Tests einrichten. Sie können dies mit dem integrierten Entwicklungsserver tun, der mit dem php-cli
-Paket geliefert wird. Zum Testen Ihres Webservers benötigen Sie auch curl
.
Wenn Sie php-cli
und/oder curl
nicht installiert haben, können Sie sie mit apt
installieren:
- sudo apt install php-cli curl
Als Nächstes erstellen Sie ein Verzeichnis, in dem Sie Ihre Webserver-Dateien speichern, und wechseln zu diesem:
- mkdir ~/www
- cd ~/www
Erstellen Sie dann eine HTML-Datei, die einen Beispieltext enthält:
- nano index.html
Fügen Sie der Datei Folgendes hinzu:
<h1>Hello, world!</h1>
Nun können Sie Ihren PHP-Webserver ausführen. Sie müssen in der Lage sein, das Webserver-Protokoll einzusehen, während Sie noch eine andere Terminal-Sitzung verwenden. Öffnen Sie dazu eine weitere Terminal-Sitzung und SSH zu Ihrem Server:
- cd ~/www
- php -S localhost:8080
Sie erhalten eine Ausgabe, die der folgenden ähnelt:
OutputPHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Wed Jan 1 16:06:41 2020
Listening on http://localhost:8080
Document root is /home/user/www
Press Ctrl-C to quit.
Sie können jetzt wieder zu Ihrer ursprünglichen Terminalsitzung zurückwechseln und mit curl
testen, ob der Webserver funktioniert:
- curl localhost:8080
Dies wird die Beispieldatei index.html
ausgeben, die Sie zuvor erstellt haben:
Output<h1>Hello, world!</h1>
Ihr Webserver muss nur lokal erreichbar sein, Sie sollten also keine Ports auf Ihrer Firewall dafür öffnen.
Nachdem Sie Ihren Testwebserver eingerichtet haben, können Sie nun damit beginnen, einen Fuzz-Test mit Radamsa durchzuführen.
Zuerst müssen Sie eine HTTP-Beispielanfrage erstellen, die als Eingabedaten für Radamsa verwendet werden soll. Erstellen Sie eine neue Datei, in der diese gespeichert wird:
- nano http-request.txt
Kopieren Sie dann die folgende HTTP-Beispielanfrage in die Datei:
GET / HTTP/1.1
Host: localhost:8080
User-Agent: test
Accept: */*
Als Nächstes können Sie Radamsa verwenden, um diese HTTP-Anfrage an Ihren lokalen Webserver zu senden. Dazu müssen Sie Radamsa als TCP-Client verwenden, was durch die Angabe einer IP-Adresse und eines Ports für die Verbindung möglich ist:
- radamsa -o 127.0.0.1:8080 http-request.txt
Anmerkung: Beachten Sie, dass die Verwendung von Radamsa als TCP-Client möglicherweise die Übertragung von fehlerhaften/bösartigen Daten über das Netzwerk verursacht. Dies kann zu Problemen führen. Achten Sie daher sehr darauf, nur auf Netzwerke zuzugreifen, die Sie testen dürfen, oder halten Sie sich vorzugsweise an die Adresse localhost (127.0.0.1
).
Wenn Sie sich die ausgegebenen Protokolle für Ihren lokalen Webserver ansehen, werden Sie feststellen, dass er die Anfragen erhalten, sie aber höchstwahrscheinlich nicht verarbeitet hat, da sie ungültig/fehlerhaft waren.
Die ausgegebenen Protokolle werden in Ihrem zweiten Terminalfenster sichtbar sein:
Output[Wed Jan 1 16:26:49 2020] 127.0.0.1:49334 Invalid request (Unexpected EOF)
[Wed Jan 1 16:28:04 2020] 127.0.0.1:49336 Invalid request (Malformed HTTP request)
[Wed Jan 1 16:28:05 2020] 127.0.0.1:49338 Invalid request (Malformed HTTP request)
[Wed Jan 1 16:28:07 2020] 127.0.0.1:49340 Invalid request (Unexpected EOF)
[Wed Jan 1 16:28:08 2020] 127.0.0.1:49342 Invalid request (Malformed HTTP request)
Für optimale Ergebnisse und um sicherzustellen, dass Abstürze aufgezeichnet werden, sollten Sie ein Automatisierungsskript ähnlich dem in Schritt 3 verwendeten schreiben. Sie sollten außerdem in Betracht ziehen, eine komplexere Eingabedatei zu verwenden, die möglicherweise Zusätze wie zusätzliche HTTP-Header enthält.
Sie haben einen Netzwerkdienst mit Radamsa als TCP-Client gefuzzt. Als Nächstes werden Sie einen Netzwerk-Client mit Radamsa als Server fuzzen.
In diesem Schritt werden Sie Radamsa zum Fuzz-Test einer Netzwerk-Client-Anwendung verwenden. Dies wird erreicht, indem die Antworten eines Netzwerkdienstes abgefangen und gefuzzt werden, bevor sie vom Client empfangen werden.
Der Zweck dieser Art des Fuzzings besteht darin, zu testen, wie belastbar Netzwerk-Client-Anwendungen gegenüber dem Empfang von fehlerhaften oder bösartigen Daten von Netzwerkdiensten sind. Zum Beispiel das Testen eines Webbrowsers (Client), der fehlerhaftes HTML von einem Webserver (Netzwerkdienst) empfängt, oder das Testen eines DNS-Clients, der fehlerhafte DNS-Antworten von einem DNS-Server empfängt.
Wie beim Fuzzing von Befehlszeilenanwendungen oder Netzwerkdiensten variiert die genaue Technik für das Fuzzing jeder Netzwerk-Client-Anwendung erheblich. In diesem Beispiel wird jedoch whois
verwendet, eine einfache TCP-basierte Sende-/Empfangsanwendung.
Die whois
-Anwendung wird verwendet, um Anfragen an WHOIS-Server zu stellen und WHOIS-Datensätze als Antworten zu erhalten. WHOIS arbeitet im Klartext über den TCP-Port 43
und ist somit ein guter Kandidat für netzwerkbasierte Fuzz-Tests.
Wenn Sie noch nicht über whois
verfügen, können Sie es mit apt
installieren:
- sudo apt install whois
Zunächst müssen Sie eine Probe der whois
-Antwort erwerben, die Sie als Eingabedaten verwenden können. Sie können dies tun, indem Sie eine whois
-Abfrage stellen und die Ausgabe in einer Datei speichern. Sie können hier jede beliebige Domäne verwenden, da Sie das whois
-Programm lokal mit Beispieldaten testen:
- whois example.com > whois.txt
Als Nächstes müssen Sie Radamsa als Server einrichten, der gefuzzte Versionen dieser whois
-Antwort liefert. Sie müssen in der Lage sein, Ihr Terminal weiter zu benutzen, sobald Radamsa im Servermodus läuft. Es wird daher empfohlen, eine weitere Terminalsitzung und eine SSH-Verbindung zu Ihrem Server zu öffnen:
- radamsa -o :4343 whois.txt -n inf
Radamsa läuft nun im TCP-Server-Modus und stellt bei jedem Verbindungsaufbau zum Server eine gefuzzte Version von whois.txt
zur Verfügung, unabhängig davon, welche Anfragedaten empfangen werden.
Sie können nun mit dem Testen der whois
-Client-Anwendung fortfahren. Sie müssen eine normale whois
-Abfrage für eine beliebige Domäne Ihrer Wahl stellen (es muss nicht dieselbe sein, für die die Beispieldaten bestimmt sind), aber mit whois
, das auf Ihren lokalen Radamsa-Server verweist:
- whois -h localhost:4343 example.com
Die Antwort wird aus Ihren Beispieldaten bestehen, die jedoch von Radamsa gefuzzt wurden. Solange Radamsa ausgeführt wird, können Sie weiterhin Anfragen an den lokalen Server stellen, und es wird jedes Mal eine andere gefuzzte Antwort ausgegeben.
Wie beim Fuzzing von Netzwerkdiensten können Sie, um die Effizienz dieses Netzwerk-Client-Fuzz-Tests zu verbessern und sicherzustellen, dass alle Abstürze erfasst werden, ein Automatisierungsskript schreiben, das dem in Schritt 3 verwendeten ähnelt.
In diesem letzten Schritt haben Sie Radamsa zur Durchführung von Fuzz-Tests einer Netzwerk-Client-Anwendung verwendet.
In diesem Artikel richteten Sie Radamsa ein und verwendeten es zum Fuzzen einer Befehlszeilenanwendung, eines Netzwerkdienstes und eines Netzwerk-Clients. Sie verfügen nun über die grundlegenden Kenntnisse, die für das Fuzz-Testen Ihrer eigenen Anwendungen erforderlich sind, hoffentlich mit dem Ergebnis, ihre Robustheit und Widerstandsfähigkeit gegen Angriffe zu verbessern.
Wenn Sie Radamsa weiter erkunden möchten, sollten Sie sich die Radamsa README
-Datei im Detail ansehen, da sie weitere technische Informationen und Beispiele für die Verwendung des Tools enthält:
Vielleicht möchten Sie sich auch einige andere Fuzzing-Tools ansehen, wie z. B. American Fuzzy Lop (AFL), ein fortschrittliches Fuzzing-Tool, das für das Testen von binären Anwendungen mit extrem hoher Geschwindigkeit und Genauigkeit entwickelt wurde:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!