
Automatiser les tâches répétitives pour le fuzzing
Je suis en train de réécrire complètement cet outil. L'accent sera mis d'abord sur les applications Linux interactives qui ne prennent que des entrées depuis stdin. J'essaie d'utiliser les fonctionnalités Driller et Fuzzer de Shellphish.
autoPwn, dans son état actuel, le fait de manière limitée. Il suffit d'exécuter autoPwn ./binary puis de sélectionner l'option Start.
Compte tenu de tous les problèmes de dépendances, le moyen le plus simple de faire fonctionner autoPwn est d'utiliser la construction Docker. Notez que vous pouvez supprimer les options --security-opt et --cap-add, mais certains aspects du fuzzing pourraient ne pas fonctionner.
$ sudo docker pull bannsec/autoPwn
$ sudo docker run -it -v $PWD:/mount --security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix/ bannsec/autopwn
Dans la construction Docker, tout est prêt à l'emploi. Vous pouvez simplement démarrer l'outil avec :
$ autoPwn ./file
autoPwn tente de faciliter la compilation du code source pour le fuzzing d'un projet. Pour cela, autoPwnCompile a été créé. Pointez-le simplement vers votre code source, donnez-lui des options, et il produira un exécutable prêt à être fuzzé.
usage: autoPwnCompile [-h] [--file FILE] [--ASAN | --MSAN] [--UBSAN]
[--fuzzer FUZZER]
Compile source to binaries for use in autoPwn.
optional arguments:
-h, --help show this help message and exit
--file FILE Single file to compile.
--ASAN Enable ASAN (default off)
--MSAN Enable MSAN (default off)
--UBSAN Enable UBSAN (default off)
--fuzzer FUZZER (optional) What fuzzer to compile for. Options are:
['AFL']. Default is AFL.
Ce qui suit provient de l'ANCIENNE version d'autoPwn..
autoPwn est un nom ambitieux pour un script simple. En travaillant avec le fuzzing et afl-fuzz, j'ai remarqué que je répétais les mêmes tâches encore et encore. Dans cette optique, j'ai voulu créer un script qui accomplirait les choses suivantes :
Jusqu'à présent, le script remplit les 5 premiers points. Le point 6 est spéculatif et est en cours de développement. Il utiliserait le moteur d'exécution symbolique angr pour créer des chemins initiaux possibles. À ce stade, le script pourrait théoriquement automatiser entièrement des tâches de fuzzing simples.
Prenons un défi récent de TUCTF appelé "WoO2". Bien qu'il ne trouve pas nécessairement l'exploit recherché, il montre comment autoPwn peut être utilisé pour simplifier la découverte de chemins.
Voici une exécution de base du programme :
$ ./e67eb287f23011a40ef5bd5c2ad2f48ca97834cf
Welcome! I don't think we're in Kansas anymore.
We're about to head off on an adventure!
Select some animals you want to bring along.
Menu Options:
1: Bring a lion
2: Bring a tiger
3: Bring a bear
4: Delete Animal
5: Exit
Enter your choice:
1
Choose the type of lion you want:
1: Congo Lion
2: Barbary Lion
1
Enter name of lion:
Test
Menu Options:
1: Bring a lion
2: Bring a tiger
3: Bring a bear
4: Delete Animal
5: Exit
Enter your choice:
5
Créons un cas de test d'entrée simple :
$ cat in/1
1
1
Test
5
Maintenant, nous pouvons facilement démarrer le fuzzer :
$ autoPwn
Setting up fuzz configuration
Target Binary (full or relative path): e67eb287f23011a40ef5bd5c2ad2f48ca97834cf
Command line args:
Number of cores (default: 8):
Test Case Dir (default: 'in/'):
Test Case Dir (default: 'out/'):
Max memory (default: 200): 4096
Starting fuzz
autoPwn> s
status check tool for afl-fuzz by <[email protected]>
Individual fuzzers
==================
>>> SESSION007 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION000 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION002 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION006 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION004 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION001 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION005 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION003 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
Summary stats
=============
Fuzzers alive : 8
Total run time : 0 days, 0 hours
Total execs : 0 million
Cumulative speed : 8 execs/sec
Pending paths : 8 faves, 8 total
Pending per fuzzer : 1 faves, 1 total (on average)
Crashes found : 0 locally unique
autoPwn> h
autoPwn
s == fuzzer (s)tatus
e == collect (e)xploits
a == collect (a)ll paths
m == (m)inimize corpus
q == (q)uit
Ce qui s'est passé ici, c'est que le script a créé des valeurs par défaut (y compris la détermination du nombre de cœurs disponibles). Nous avons modifié une valeur par défaut car nous avions besoin de mémoire supplémentaire pour exécuter cela dans QEMU. autoPwn a créé un fichier de configuration qu'il a ensuite transmis à afl-utils (https://github.com/rc0r/afl-utils). Dans le fichier de configuration, il a également configuré les affinités CPU, de sorte que le fuzzing soit optimal par défaut.
À ce stade, votre ordinateur se lance dans le fuzzing. Cependant, un aspect clé du fuzzing est la minimisation du corpus. Dans cette optique, autoPwn surveille l'instance afl-fuzz pour détecter quand une série de mutations est terminée. Lorsque cela se produit, il arrête le fuzzing (non optimal, mais acceptable pour l'instant), minimise le corpus, puis redémarre le fuzzing. Il le fait sans aucune intervention humaine, vous pouvez donc lancer et oublier.
À un moment donné, vous voudrez peut-être jeter un œil aux chemins qu'afl a trouvés. En exécutant la commande "a", autoPwn copiera tous les chemins connus, minimisera le corpus puis minimisera les cas eux-mêmes et les fournira dans un répertoire de sortie.