
A linux system call fuzzer using TriforceAFL
Nouveau : pour ceux qui souhaitent jouer avec TriforceAFL et TLSF, Richard Johnson a créé un Dockerfile qui installe les deux (et construit même un noyau Linux pour vous). Il est disponible ici https://hub.docker.com/r/moflow/afl-triforce/tags/.
Ceci est une collection de fichiers utilisés pour effectuer du fuzzing
des appels système des noyaux Linux x86_64 à l'aide d'AFL et de QEMU. Pour
l'utiliser, vous aurez besoin de TriforceAFL depuis https://github.com/nccgroup/TriforceAFL
et d'une image de noyau à fuzzer. Les scripts supposent que TriforceAFL se
trouve dans $TAFL ou ../TriforceAFL/ (N.B. la compilation de testAfl nécessite
que ../TriforceAFL/config.h existe).
Pour compiler :
make
Pour exécuter, installez d'abord un noyau dans ./kern/bzImage et
extrayez /proc/kallsyms
dans ./kern/kallsyms. Définissez la variable d'environnement K=kern pour
pointer vers votre noyau. Exécutez ensuite :
make inputs
./runFuzz -M M0
Notez que le script runFuzz attend un nom de maître ou d'esclave, car
il s'exécute toujours en mode maître/esclave. Consultez le script runFuzz pour
plus d'informations sur l'utilisation.
Notez également que cela ne crée qu'un petit ensemble d'exemples d'entrées. Pour tester
un grand nombre d'appels système importants, vous voudrez probablement
générer un exemple de chaque appel système, ou au moins un exemple
pour chaque « forme » d'appel système. Ceux-ci doivent être placés dans inputs/.
Voir gen2.py pour un exemple.
Pour reproduire des cas de test (tels que des plantages), exécutez :
./runTest inputs/ex1
./runTest outputs/crashes/id*
Vous pouvez également exécuter le pilote hors de l'environnement émulé
avec l'option -t, avec une journalisation détaillée avec -vv
et sans réellement effectuer les appels système avec -x :
./driver -tvvx < inputs/ex1
strace ./driver -t < inputs/ex1
Il est parfois utile de pouvoir démarrer le noyau et d'exécuter des tests de manière interactive. Pour ce faire, modifiez les fichiers rootTemplate comme bon vous semble (par exemple, pour ajouter d'autres outils de test au système de fichiers racine), puis exécutez :
./runCmd
D'autres commandes que le shell peuvent être invoquées en les passant
en arguments de ligne de commande à runCmd.
Remarque : lorsque vous avez terminé avec le shell, utilisez ^A-c pour obtenir
l'invite QEMU et tapez quit.
Le débogage est plus facile avec un noyau compilé avec les symboles de débogage
activés. Utilisez runTest pour démarrer le noyau et exécuter un test via le
pilote, ou utilisez runCmd pour exécuter manuellement un cas de test depuis le shell.
Modifiez votre script de lancement pour inclure l'option -s lors du démarrage
de afl-qemu-system-trace. Cela activera la prise en charge de gdb sur le port
TCP 1234. Utilisez getvmlinux pour extraire l'image du noyau vmlinux de votre
noyau bzImage et exécutez gdb une fois le système démarré :
cp kern/bzImage .
./getvmlinux
gdb ./vmlinux
target remote :1234
break somefunction
continue
Vous pouvez attacher le débogueur après que runTest a provoqué un plantage
ou avant de déclencher manuellement le bug dans runCmd.
Notez que les sources Linux sont compilées avec l'optimisation activée
par défaut. Cela peut rendre le débogage confus et difficile.
Vous pouvez désactiver l'optimisation fichier par fichier
en éditant le fichier make de Linux pour le sous-répertoire dans lequel un
fichier se trouve et en ajoutant CFLAGS_name.o = -O0 au Makefile. Par
exemple, éditer kernel/Makefile et ajouter CFLAGS_sys_ni.o = -O0
désactivera l'optimisation lors de la compilation de kernel/sys_ni.o.
Le script shell getSyms utilise runCmd pour exécuter cat /proc/kallsyms
et l'extraire dans un fichier local nommé kallsyms. Ceci est généralement
utilisé pour préparer votre noyau au fuzzing :
K=yourKernDir ./getSyms pour obtenir kallsymsmv kallsyms yourKernDir pour l'installerRemarque : lors du fuzzing d'un noyau Linux 2., vous devrez activer
la minuterie du processeur. Lorsque la minuterie n'est pas activée, la détection
des panics et la journalisation ne semblent pas fonctionner correctement et les
panics entraînent des blocages. Pour activer la minuterie, appelez
startForkserver(1) dans driver.c au lieu de startForkserver(0). Ce problème
ne semble pas se produire dans les noyaux Linux 3. et Linux 4.*.