
Fuzzer DOM
Écrit et maintenu par Ivan Fratric, [email protected]
Copyright 2017 Google Inc. Tous droits réservés.
Licencié sous la Licence Apache, version 2.0 (la « Licence ») ; vous ne pouvez utiliser ce fichier que conformément à la Licence. Vous pouvez obtenir une copie de la Licence à l'adresse suivante :
http://www.apache.org/licenses/LICENSE-2.0
Sauf lorsque la loi applicable l'exige ou lorsque cela a été convenu par écrit, le logiciel distribué sous la Licence est distribué « TEL QUEL », SANS GARANTIES NI CONDITIONS D'AUCUNE SORTE, expresses ou implicites. Voir la Licence pour connaître les autorisations et limitations spécifiques régissant la Licence.
Pour afficher les informations d'utilisation, exécutez la commande suivante :
python3 generator.py --help
Pour générer un seul échantillon .html, exécutez :
python generator.py --file <output file>
Pour générer un seul échantillon .html à l'aide d'un modèle que vous avez écrit :
python generator.py --file <output file> --template <your custom template file>
Pour générer plusieurs échantillons en un seul appel, exécutez :
python generator.py --output_dir <output directory> --no_of_files <number of output files>
Les échantillons générés seront placés dans le répertoire spécifié et seront nommés fuzz-<number>.html, par exemple fuzz-00001.html, fuzz-00002.html, etc. La génération de plusieurs échantillons est plus rapide car les fichiers de grammaire d'entrée ne doivent être chargés et analysés qu'une seule fois.
generator.py contient le script principal. Il utilise grammar.py comme bibliothèque et contient du code d'assistance supplémentaire pour le fuzzing DOM.
grammar.py contient le moteur de génération, qui est en grande partie indépendant de l'application et peut donc être utilisé dans d'autres fuzzers basés sur la génération (c'est-à-dire non-DOM). Comme il peut être utilisé comme bibliothèque, son utilisation est décrite dans une section séparée ci-dessous.
Les fichiers .txt contiennent les définitions de grammaire. Il y a 3 fichiers principaux, html.txt, css.txt et js.txt, qui contiennent respectivement les grammaires HTML, CSS et JavaScript. Ces fichiers de grammaire racines peuvent inclure du contenu provenant d'autres fichiers.
Pour utiliser le moteur de génération avec une grammaire personnalisée, vous pouvez utiliser le code Python suivant :
from grammar import Grammar
my_grammar = Grammar()
my_grammar.parse_from_file('input_file.txt')
result_string = my_grammar.generate_symbol('symbol_name')
Les sections suivantes décrivent la syntaxe des fichiers de grammaire.
Domato est basé sur un moteur qui, à partir d'une grammaire hors contexte dans un format simple spécifié ci-dessous, génère des échantillons à partir de cette grammaire.
Une grammaire est décrite comme un ensemble de règles au format de base suivant :
<symbol> = a mix of constants and <other_symbol>s
Chaque règle de grammaire contient un côté gauche et un côté droit séparés par le caractère égal. Le côté gauche contient un symbole, tandis que le côté droit contient les détails sur la façon dont ce symbole peut être développé. Lors du développement d'un symbole, tous les symboles du côté droit sont développés récursivement, tandis que tout ce qui n'est pas un symbole est simplement copié dans la sortie. Notez qu'une seule règle ne peut pas s'étendre sur plusieurs lignes du fichier d'entrée.
Considérez l'exemple simplifié suivant d'une partie de la grammaire CSS :
<cssrule> = <selector> { <declaration> }
<selector> = a
<selector> = b
<declaration> = width:100%
Si nous demandons au moteur de grammaire d'analyser cette grammaire et de générer 'cssrule', nous pouvons obtenir soit :
a { width:100% }
soit
b { width:100% }
Notez qu'il existe deux règles pour le symbole 'selector'. Dans de tels cas, lorsque le générateur est invité à générer un 'selector', il choisit la règle à utiliser de manière aléatoire. Il est également possible de spécifier la probabilité de la règle à l'aide de l'attribut 'p', par exemple :
<selector p=0.9> = a
<selector p=0.1> = b
Dans ce cas, la chaîne 'a' serait produite plus souvent que 'b'.
Il existe d'autres attributs qui peuvent être appliqués aux symboles en plus de la probabilité. Ils sont listés dans une section séparée.
Considérez un autre exemple pour la génération d'échantillons HTML :
<html> = <lt>html<gt><head><body><lt>/html<gt>
<head> = <lt>head<gt>...<lt>/head<gt>
<body> = <lt>body<gt>...<lt>/body<gt>
Notez que, comme les caractères '<' et '>' ont une signification particulière dans la syntaxe de la grammaire, nous utilisons ici <lt> et <gt> à la place. Ces symboles sont intégrés et n'ont pas besoin d'être définis par l'utilisateur. Une liste de tous les symboles intégrés est fournie dans une section séparée.
Pour générer du code de langage de programmation, une syntaxe similaire peut être utilisée, mais il y a quelques différences. Chaque ligne de la grammaire du langage de programmation correspondra à une ligne de la sortie. Pour cette raison, la syntaxe de la grammaire sera plus libre afin de permettre d'exprimer des constructions dans divers langages de programmation. Deuxièmement, lorsqu'une ligne est générée, en plus de produire la ligne, une ou plusieurs variables peuvent être créées et ces variables peuvent être réutilisées lors de la génération d'autres lignes. Reprenons l'exemple simplifié :
!varformat fuzzvar%05d
!lineguard try { <line> } catch(e) {}
!begin lines
<new element> = document.getElementById("<string min=97 max=122>");
<element>.doSomething();
!end lines
Si nous demandons au moteur de générer 5 lignes, nous pouvons obtenir quelque chose comme :
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) {}
Notez que
<new element> au lieu de <element>. Cela demande au générateur de créer une nouvelle variable de type 'element' au lieu de générer le symbole 'element'.<string> est l'un des symboles intégrés, il n'est donc pas nécessaire de le définir.Tout ce qui suit le premier caractère '#' sur la ligne est considéré comme un commentaire, par exemple :
#This is a comment