
Un fuzzer évolutionnaire basé sur les connaissances.
Ce document vise à expliquer brièvement la théorie derrière Choronzon. De plus, il fournit des détails sur ses mécanismes internes et comment on peut étendre Choronzon pour répondre à de nouvelles exigences. Un aperçu de l'architecture de Choronzon a été initialement présenté lors de la Conférence ZeroNights 2015. Un enregistrement de la présentation et les diapositives sont également disponibles.
Choronzon est un fuzzer évolutionnaire. Il essaie d'imiter le processus évolutionnaire afin de continuer à produire de meilleurs résultats. Pour y parvenir, il dispose d'un système d'évaluation pour classer les fichiers fuzzés qui sont intéressants et ceux qui doivent être abandonnés.
De plus, Choronzon est un fuzzer basé sur la connaissance. Il utilise des informations définies par l'utilisateur pour lire et écrire des fichiers du format cible. Pour se familiariser avec la terminologie de Choronzon, il faut considérer que chaque fichier est représenté par un chromosome. Les utilisateurs doivent décrire la structure élémentaire du format de fichier considéré. Un aperçu de haut niveau du format de fichier est préféré plutôt que de décrire chaque détail et aspect. Chacune de ces structures élémentaires définies par l'utilisateur est considérée comme un gène. Chaque chromosome contient un arbre de gènes et est capable de construire le fichier correspondant à partir de celui-ci.
Choronzon est divisé en trois sous-systèmes : le module Tracer, le module Chromosome et le fuzzer.
Brièvement, le composant Chromosome est utilisé pour décrire le format de fichier cible. Les utilisateurs peuvent écrire leurs propres modules pour prendre en charge de nouveaux formats ou des formats personnalisés. À titre d'exemple, un module PNG est fourni avec .
D'autre part, le composant Tracer est responsable de surveiller l'application cible et de collecter diverses informations sur son exécution. Cette version de Choronzon utilise l'outil d'instrumentation binaire Intel's Pin afin d'enregistrer les blocs de base qui ont été visités pendant l'exécution. Cependant, Choronzon est capable de prendre en charge d'autres backends de traçage également. Gardez également à l'esprit que dans la prochaine version de Choronzon, Pin sera remplacé en raison de son impact sur les performances.
Enfin, le composant fuzzer est utilisé pour modifier le contenu des fichiers à tester. Le module contient un corpus de Mutators et Recombinators. Les Mutators, simplement, modifient le fichier comme le font les fuzzers courants. Par exemple, ils effectuent du byte flipping, du byte swapping, une mutation aléatoire d'octets, etc. Mais Choronzon possède une autre fonctionnalité qui n'est pas aussi courante parmi les fuzzers. Les Recombinators utilisent les informations sur la structure du format de fichier, fournies par le module Chromosome, afin d'effectuer un fuzzing intelligent.
Dans le répertoire chromosome/parsers, vous trouverez le fichier PNG.py. Ce
module Python décrit le format de fichier PNG au fuzzer. Vous pouvez ajouter vos
modules personnalisés pour d'autres formats de fichiers dans ce répertoire.
L'idée fondamentale derrière le sous-système Chromosome est de convertir les fichiers seed initiaux en un arbre de Genes à l'aide d'un Deserializer. À un moment donné, les Genes (fuzzés) seront écrits dans un fichier, à l'aide d'un Serializer.
Considérez que dans Choronzon, le but du module analyseur est de fournir la structure élémentaire du format de fichier, plutôt que chaque détail mineur. Cela aidera le fuzzer à construire des fichiers qui sont la plupart du temps valides, évitant une sortie prématurée de l'application cible. De plus, cette approche permet de gagner du temps, car décrire chaque aspect du format de fichier prend du temps et introduit une charge de développement importante.
Un nouveau module analyseur doit importer :
et il doit implémenter
Dans l'exemple fourni avec Choronzon, chaque PNGGene correspond à un chunk PNG. En général, vous pouvez considérer un Gene comme une structure de données élémentaire du format cible. Chaque Chromosome est constitué d'un arbre de Genes, et représente un fichier unique. Chaque Gene doit être capable de produire une chaîne d'octets qui contient ses données combinées avec les données des Genes inférieurs dans l'arbre.
Le PNGSerializer doit être capable de produire un fichier (la plupart du temps valide) à partir d'une liste de Genes qui lui est donnée. D'autre part, PNGDeserializer doit être capable d'analyser un fichier valide du format cible et de le désérialiser en un arbre de Genes.
Consultez chromosome/parsers/PNG.py pour un exemple commenté du format PNG.
Le module Tracer est utilisé pour désassembler l'application cible (et/ou une ou plusieurs de ses bibliothèques). Dans cette version de Choronzon, cela est réalisé avec IDA. Nous avons utilisé cette approche car nous pouvons corréler toute information intéressante de la campagne de fuzzing avec nos IDBs. Cependant, nous pourrions supprimer la dépendance à IDA dans un avenir proche afin de rendre Choronzon plus portable et accessible.
Un fichier est testé contre une application à l'aide d'un utilitaire Pin. Dans le
répertoire analyzer/coverage se trouve le code source de cet outil Pin, qui
injecte des hooks au début de chaque bloc de base dans l'application cible.
Lorsque l'exécution est terminée, nous corrélons le bloc de base qui a été touché avec
le bloc de base du binaire. Ainsi, nous pouvons calculer des métriques qui sont
précieuses pour nous (couverture, etc.).
Le composant Fuzzer utilise la représentation Chromosome pour fuzzer un fichier. Comme mentionné précédemment, il existe deux méthodes de fuzzing dans Choronzon.
Pour la première méthode, Choronzon récupère le contenu d'un ou plusieurs gènes
et applique l'un des Mutators. Les Mutators implémentent des méthodes de fuzzing courantes mais efficaces
comme la mutation aléatoire d'octets, le high bit set, le byte swapping
et bien d'autres. Vous pouvez également écrire vos propres mutateurs personnalisés et les ajouter dans
fuzzers/mutators.py.
La seconde méthode de fuzzing s'appelle la recombinaison. Les Recombinators sont utilisés pour modifier la structure du fichier. Voici un exemple avec le format PNG.
Les fichiers PNG sont composés de chunks consécutifs qui contiennent quatre champs :
Supposons que nous ayons un fichier PNG qui ne contient que des chunks IHDR, IDAT et IEND. Sa structure ressemblerait à ceci :
[ PNG signature ] [ IHDR ] [ IDAT ] [ IEND ]
Comme Choronzon connaît les structures de base (c'est-à-dire les chunks PNG), il est capable de modifier leur séquence. Après une recombinaison réussie, le fichier PNG fuzzé de sortie peut ressembler à ceci :
[ PNG signature ] [ IDAT ] [ IHDR ] [ IEND ]
Choronzon contient de nombreuses autres stratégies de recombinaison qui lui permettent de faire face même à des formats de fichiers complexes.
Choronzon a été testé avec Python 2.7, Pin 3, IDA Pro 6.6 à 6.9, sur Ubuntu 16.04 LTS (noyau Linux 4.4) et Windows 10.
Pour l'exécuter, vous devrez installer le paquet Python sortedcontainers. Vous pouvez le trouver ici ou l'installer via pip.
De plus, Choronzon nécessite IDA Pro (en fait, sa version terminale). Le chemin d'IDA Pro doit être spécifié dans votre fichier de configuration comme ceci :
DisassemblerPath = 'C:\\Program Files (x86)\\IDA 6.6'
Il a été testé avec succès avec IDA Pro 6.6, 6.7, 6.8 et 6.9.
L'outil Pin de couverture de Choronzon se trouve dans analyzer/coverage et doit être
compilé. Vous pouvez consulter la documentation de Pin pour plus de détails, ou vous pouvez
effectuer les étapes suivantes :
coverage.cpp et makefile.rules dans
/path/to/pin/source/tools/MyPinToolmake. Si vous êtes sous Windows, vous devez lancer la ligne de commande
Visual Studio et utiliser l'utilitaire make et ses dépendances depuis
Cygwin/path/to/choronzon/analysis/coverage le répertoire nouvellement créé
obj-intel64 (ou obj-ia32 pour les systèmes 32 bits)Pour fuzzer avec Choronzon, vous devez fournir un fichier de
configuration. Dans le répertoire settings se trouve un exemple de configuration
de Choronzon.