
DOM-Fuzzer
Geschrieben und gepflegt von Ivan Fratric, [email protected]
Copyright 2017 Google Inc. All Rights Reserved.
Lizenziert unter der Apache-Lizenz, Version 2.0 (die "License"); Sie dürfen diese Datei nur in Übereinstimmung mit der Lizenz verwenden. Eine Kopie der Lizenz erhalten Sie unter
http://www.apache.org/licenses/LICENSE-2.0
Sofern nicht durch geltendes Recht gefordert oder schriftlich vereinbart, wird die Software unter der Lizenz auf einer "AS IS"-BASIS verteilt, OHNE GEWÄHRLEISTUNG ODER BEDINGUNGEN JEGLICHER ART, weder ausdrücklich noch implizit. Siehe die Lizenz für die spezifischen Berechtigungen und Beschränkungen der Lizenz.
Um die Verwendungsinformationen anzuzeigen, führen Sie den folgenden Befehl aus:
python3 generator.py --help
Um eine einzelne .html-Beispieldatei zu generieren, führen Sie Folgendes aus:
python generator.py --file <output file>
Um eine einzelne .html-Beispieldatei mit einer selbst erstellten Vorlage zu generieren, führen Sie Folgendes aus:
python generator.py --file <output file> --template <your custom template file>
Um mehrere Beispieldateien mit einem einzigen Aufruf zu generieren, führen Sie Folgendes aus:
python generator.py --output_dir <output directory> --no_of_files <number of output files>
Die generierten Beispieldateien werden im angegebenen Verzeichnis abgelegt und wie folgt benannt: fuzz-<number>.html, z. B. fuzz-00001.html, fuzz-00002.html usw. Das Generieren mehrerer Beispieldateien ist schneller, da die Eingabe-Grammatikdateien nur einmal geladen und geparst werden müssen.
generator.py enthält das Hauptskript. Es verwendet grammar.py als Bibliothek und enthält zusätzlichen Hilfscode für das DOM-Fuzzing.
grammar.py enthält die Generierungsengine, die weitgehend anwendungsunabhängig ist und daher auch in anderen (d. h. Nicht-DOM-) generierungsbasierten Fuzzern verwendet werden kann. Da sie als Bibliothek verwendet werden kann, wird ihre Verwendung weiter unten in einem separaten Abschnitt beschrieben.
.txt-Dateien enthalten Grammatikdefinitionen. Es gibt 3 Hauptdateien: html.txt, css.txt und js.txt, die die HTML-, CSS- bzw. JavaScript-Grammatiken enthalten. Diese Wurzel-Grammatikdateien können Inhalte aus anderen Dateien einbinden.
Um die Generierungsengine mit einer benutzerdefinierten Grammatik zu verwenden, können Sie den folgenden Python-Code nutzen:
from grammar import Grammar
my_grammar = Grammar()
my_grammar.parse_from_file('input_file.txt')
result_string = my_grammar.generate_symbol('symbol_name')
Die folgenden Abschnitte beschreiben die Syntax der Grammatikdateien.
Domato basiert auf einer Engine, die Beispieldateien aus einer kontextfreien Grammatik in einem einfachen, unten angegebenen Format generiert.
Eine Grammatik wird als eine Reihe von Regeln im folgenden Grundformat beschrieben:
<symbol> = a mix of constants and <other_symbol>s
Jede Grammatikregel enthält eine linke Seite und eine rechte Seite, die durch das Gleichheitszeichen getrennt sind. Die linke Seite enthält ein Symbol, während die rechte Seite die Details darüber enthält, wie dieses Symbol expandiert werden darf. Beim Expandieren eines Symbols werden alle Symbole auf der rechten Seite rekursiv expandiert, während alles, was kein Symbol ist, einfach in die Ausgabe kopiert wird. Beachten Sie, dass eine einzelne Regel nicht über mehrere Zeilen der Eingabedatei verlaufen kann.
Betrachten Sie das folgende vereinfachte Beispiel eines Teils der CSS-Grammatik:
<cssrule> = <selector> { <declaration> }
<selector> = a
<selector> = b
<declaration> = width:100%
Wenn wir die Grammatik-Engine anweisen, diese Grammatik zu parsen und 'cssrule' zu generieren, erhalten wir möglicherweise entweder:
a { width:100% }
oder
b { width:100% }
Beachten Sie, dass es zwei Regeln für das Symbol 'selector' gibt. In solchen Fällen wählt der Generator, wenn er aufgefordert wird, einen 'selector' zu generieren, die zu verwendende Regel zufällig aus. Es ist auch möglich, die Wahrscheinlichkeit der Regel über das 'p'-Attribut anzugeben, zum Beispiel:
<selector p=0.9> = a
<selector p=0.1> = b
In diesem Fall würde die Zeichenkette 'a' häufiger ausgegeben als 'b'.
Zusätzlich zur Wahrscheinlichkeit gibt es weitere Attribute, die auf Symbole angewendet werden können. Diese sind in einem separaten Abschnitt aufgeführt.
Betrachten Sie ein weiteres Beispiel zum Generieren von HTML-Beispieldateien:
<html> = <lt>html<gt><head><body><lt>/html<gt>
<head> = <lt>head<gt>...<lt>/head<gt>
<body> = <lt>body<gt>...<lt>/body<gt>
Beachten Sie, dass '<' und '>' in der Grammatiksyntax eine besondere Bedeutung haben; daher verwenden wir hier stattdessen <lt> und <gt>. Diese Symbole sind eingebaut und müssen nicht vom Benutzer definiert werden. Eine Liste aller eingebauten Symbole befindet sich in einem separaten Abschnitt.
Zum Generieren von Programmiersprachencode kann eine ähnliche Syntax verwendet werden, allerdings gibt es einige Unterschiede. Jede Zeile der Programmiersprachen-Grammatik entspricht einer Zeile der Ausgabe. Aus diesem Grund ist die Grammatiksyntax freier gestaltet, um Konstrukte in verschiedenen Programmiersprachen ausdrücken zu können. Zweitens können beim Generieren einer Zeile zusätzlich zur Ausgabe der Zeile eine oder mehrere Variablen erstellt werden, die bei der Generierung anderer Zeilen wiederverwendet werden können. Auch hierzu schauen wir uns das vereinfachte Beispiel an:
!varformat fuzzvar%05d
!lineguard try { <line> } catch(e) {}
!begin lines
<new element> = document.getElementById("<string min=97 max=122>");
<element>.doSomething();
!end lines
Wenn wir die Engine anweisen, 5 Zeilen zu generieren, erhalten wir möglicherweise etwa Folgendes:
try { var00001 = document.getElementById("hw"); } catch(e) {}
try { var00001.doSomething(); } catch(e) {}
try { var00002 = document.getElementById("feezcqbndf"); } catch(e) {}
try { var00002.doSomething(); } catch(e) {}
try { var00001.doSomething(); } catch(e) {}
Beachten Sie, dass
<new element> anstelle von <element> verwendet. Dies weist den Generator an, eine neue Variable vom Typ 'element' zu erstellen, anstatt das Symbol 'element' zu generieren.<string> ist eines der eingebauten Symbole, daher muss es nicht definiert werden.Alles nach dem ersten '#'-Zeichen in der Zeile gilt als Kommentar, zum Beispiel:
#This is a comment