
Ein strukturbewusster JSON-Fuzzer

jdam ist ein von [Radamsa] inspiriertes Werkzeug zum Fuzzing beliebiger JSON-Objekte in einer strukturbewussten Weise, die sicherstellt, dass Fuzzing-Ergebnisse immer gültiges JSON sind.
Viele bestehende Fuzzing-Tools verändern die Eingabe blind und führen oft dazu, dass das Ergebnis ungültiges JSON ist. Das bedeutet, dass Fuzz-Tests nur den JSON-Parser der Zielanwendung testen und die Fuzz-Tests nie den darunterliegenden Anwendungscode erreichen, da die Anfragen ungültig sind. Jdam ist ein Versuch, dieses Problem zu lösen.
jdam verfügt über mehrere Mutationsmodule, die alle darauf abzielen, potenzielle Probleme und Schwachstellen in den Systemen aufzudecken, die die gefuzten Daten verarbeiten. Einige Module führen zufällige Änderungen durch, wie das Löschen, Ersetzen, Vertauschen und Wiederholen von zufälligen Bytes, das Invertieren von booleschen Werten und die Negation von Zahlen, während andere Module Werte durch Payloads ersetzen, die versuchen, bestimmte Schwachstellentypen auszulösen, wie z.B.:
Um eine vollständige Liste der verfügbaren Mutatoren zu sehen, verwenden Sie jdam -list.
jdam ist noch recht grob und Fehler sind zu erwarten. Es ist jedoch stabil genug, um für die abenteuerlustigen Leute da draußen veröffentlicht zu werden, aber betrachten Sie es vorerst als Alpha-Software!
Laden Sie ein vorgefertigtes [Release] für Ihr Betriebssystem herunter oder klonen Sie das Repository und kompilieren Sie es mit go build -o jdam cmd/jdam/*.
Usage of jdam:
-count int
Number of fuzzed objects to generate (default 1)
-ignore string
Comma-separated list of fields to exclude from fuzzing
-list
List available mutators
-max-depth int
Maximum object depth to fuzz (default 100)
-mutators string
Comma-separated list of mutator IDs to use (default: all)
-nil-chance float
Probability of value being set to nil (between 0 (no nils) and 1 (all nils)) (default 0.75)
-output string
Output file pattern to use for results (e.g. /tmp/jdam-%d.json)
-rounds int
Number of times to fuzz object (default 1)
-seed int
Seed to use for pseudo-random number generator (default: current UNIX timestamp)
-verbose
Print activity information
-version
Print current jdam version
jdam funktioniert, indem ein gültiges JSON-Objekt ({...}) hineingeleitet wird. Standardmäßig führt jdam eine zufällige Permutation auf einem zufälligen Feld durch und gibt das resultierende JSON-Objekt aus:
$ echo '{"hello":"world"}' | jdam
{"hello":{"id":1}}
Das betreffende JSON kann mit dem Flag -rounds mehrmals mutiert werden, aber beachten Sie, dass auch vorherige Fuzzing-Payloads mutiert werden können:
$ echo '{"hello":"world"}' | jdam -rounds 10
{"hello":{"_constructor":"${42*444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444442}"}}
Mehrere gefuzte Objekte können mit dem Flag -count generiert werden:
$ echo '{"hello":"world"}' | jdam -count 10
{"hello":"sorld"}
{"hello":"../../../../../../../../../../../../../../../../../../../../etc/passwd"}
{"hello":"{{42*42}}"}
{"hello":null}
{"hello":"' \u0026\u0026 this.password.match(/.*/)//+\u0000"}
{"hello":{"$where":"1"}}
{"hello":"null"}
{"hello":"\";touch /tmp/jdam.70797.fail'"}
{"hello":null}
{"hello":"|| 1==1"}
jdam kann Fuzzing-Ergebnisse in einzelne Dateien schreiben, wenn Sie Testdateien vorbereiten möchten, anstatt die STDOUT des Befehls zu verwenden:
$ echo '{"hello":"world"}' | jdam -count 10 -output "/tmp/jdam-%d.json"
Der obige Befehl generiert 10 Dateien in /tmp von jdam-1.json bis jdam-10.json. Das spezielle Verb %d wird automatisch durch eine fortlaufende Nummer ersetzt, sodass Ergebnisse in einzelne Dateien geschrieben werden können.
Wenn Sie sicherstellen möchten, dass jdam bestimmte Felder im betreffenden JSON-Objekt niemals mutiert, können Sie jdam anweisen, diese mit dem Flag -ignore zu ignorieren:
$ echo '{"id":13,"articleId":37,"comment":"Hello"}' | ./jdam -count 10 -ignore id,articleId
{"id":13,"articleId":37,"comment":"%x%x%x%x"}
{"id":13,"articleId":37,"comment":"search=')] | //user/*[contains(*,'"}
{"id":13,"articleId":37,"comment":"' and count(/comment())=1 and '1'='1"}
{"id":13,"articleId":37,"comment":"\u0016ello"}
{"id":13,"articleId":37,"comment":"/"}
{"id":13,"articleId":37,"comment":null}
{"id":13,"articleId":37,"comment":"{{{42*42}}}"}
{"id":13,"articleId":37,"comment":"@*"}
{"id":13,"articleId":37,"comment":"Helloooooooooooooooo"}
{"id":13,"articleId":37,"comment":"//*"}
[ffuf] ist ein fantastischer Web-Fuzzer und jdam kann leicht als Eingabe für Fuzzing verwendet werden:
ffuf -input-cmd 'cat subject.json | jdam -rounds 3' -d FUZZ -u http://localhost/api/todos/1 -X PUT -v -mc 500 -mr 'error|failed|failure|fault|abort|root:|1764|0x|\d{20}' -od /tmp/ffuf_test
Der obige Befehl weist ffuf an, seine Fuzzing-Eingabe von jdam zu beziehen und sie als Anforderungstext an PUT /api/todos/1 zu senden. Anforderungs- und Antwortdetails werden in tmp/ffuf_test/ geschrieben, wenn die Antwort 500 Internal Server Error ist oder wenn der Antworttext bestimmte interessante Zeichenketten enthält.
Wenn Sie [Go] kennen und ein sehr spezialisiertes Fuzzing benötigen, können Sie jdam in Ihrem eigenen Go-Code verwenden. Weitere Verwendungsbeispiele finden Sie im Ordner examples/.
Fuzzing ist nur nützlich, wenn Sie erkennen können, dass eine bestimmte Mutation ein Problem verursacht oder eine Schwachstelle ausgelöst hat. Diese Anzeichen variieren je nach Zielsystem und Umgebung, aber hier sind einige gute allgemeine Dinge, auf die Sie achten sollten: