
Ce fuzzer expérimental est destiné à être utilisé pour le fuzzing en mémoire d'API.
v1.4 Copyright (C) 2020 Andrea Fioraldi [email protected]
Publié sous licence Apache v2.0
Ce fuzzer expérimental est destiné au fuzzing d'API en mémoire.
Sa conception est fortement inspirée et basée sur AFL/AFL++.
À l'heure actuelle, le mutateur est assez simple, seuls les stages havoc et splice d'AFL sont implémentés.
Je n'ai testé que les exemples présents dans tests/, c'est un projet en cours mais il fonctionne au moins sur GNU/Linux x86_64 et Android x86_64.
Vous avez besoin de Frida >= 12.8.1 pour l'exécuter (pip3 install -U frida) et de frida-tools pour compiler le harnais.
La bibliothèque fuzz doit être importée dans un harnais personnalisé, puis compilée avec frida-compile pour générer l'agent que frida-fuzzer injectera dans l'application cible.
La majeure partie de la logique du fuzzer se trouve dans l'agent.
Un harnais a le format suivant :
var fuzz = require("./fuzz");
var TARGET_MODULE = "test_linux64";
var TARGET_FUNCTION = DebugSymbol.fromName("target_func").address;;
var RET_TYPE = "void";
var ARGS_TYPES = ['pointer', 'int'];
var func_handle = new NativeFunction(TARGET_FUNCTION, RET_TYPE, ARGS_TYPES, { traps: 'all' });
fuzz.target_module = TARGET_MODULE;
var payload_mem = Memory.alloc(fuzz.config.MAX_FILE);
fuzz.fuzzer_test_one_input = function (/* Uint8Array */ payload) {
Memory.writeByteArray(payload_mem, payload, payload.length);
func_handle(payload_mem, payload.length);
}
fuzz.fuzzer_test_one_input est obligatoire. Si vous ne spécifiez pas fuzz.target_module, tout le code exécuté sera instrumenté.
Vous pouvez également définir fuzz.manual_loop_start = true pour indiquer au fuzzer que vous appellerez fuzz.fuzzing_loop() dans un callback et qu'il ne doit donc pas l'appeler pour vous (par exemple, pour démarrer le fuzzing lorsqu'un bouton est cliqué dans l'application Android).
Le callback fuzz.init_callback peut être défini pour exécuter du code lorsque le fuzzer est prêt à commencer. Voir tests/test_java.js pour un exemple.
fuzz.dictionary est un dictionnaire de fuzzer classique, un tableau dans lequel vous pouvez ajouter des éléments (les types acceptés sont Array, ArrayBuffer, Uint8Array, String) qui sont utilisés comme valeurs supplémentaires dans le mutateur. Voir tests/test_libxml2.js pour un exemple.
frida-fuzzer accepte les arguments suivants :
Si vous ne spécifiez pas le dossier de sortie, un dossier temporaire est créé dans /tmp.
Si vous ne spécifiez pas le dossier contenant la seed initiale, une seed non informée 0000 est utilisée comme seed de départ.
Si vous fuzzez une application locale, vous pouvez exécuter system-config avant frida-fuzzer pour ajuster les paramètres de votre système et accélérer les choses.
En exécutant ./frida-fuzzer -spawn ./tests/test_linux64, vous verrez un écran de statut similaire à celui-ci sur votre terminal :

Vous pouvez aussi facilement ajouter un stage personnalisé dans fuzz/fuzzer.js et l'ajouter à la liste des stages dans fuzz/index.js.
Pour personnaliser le fuzzer, modifiez fuzz/config.js.
Les variables que vous voudrez peut-être modifier sont MAP_SIZE (si le code que vous fuzzez est petit, vous pouvez le réduire pour gagner un peu de vitesse), MAX_FILE (la taille maximale de l'entrée générée) et QUEUE_CACHE_MAX_SIZE (augmenter la taille du cache de la file pour plus de vitesse, surtout sur Android).
Fuzzons la bibliothèque partagée native dans l'application Android d'exemple dans tests.
Assurez-vous d'avoir les droits root sur votre appareil virtuel :
host$ adb root
Téléchargez le frida-server Android x86_64 depuis la page de release du dépôt et copiez-le sur l'appareil sous /data/local/tmp (utilisez adb push).
Lancez un shell et exécutez le frida-server :
device# cd /data/local/tmp
device# ./frida-server
Installez maintenant l'application de test tests/app-debug.apk en la glissant-déposant dans la fenêtre de l'émulateur.
Ouvrez ensuite l'application.
Compilez le script agent avec frida-compile :
host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js
Ouvrez l'application dans l'émulateur.
Fuzzzez la fonction test_func de la bibliothèque libnative-lib.so fournie avec l'application de test
avec la commande :
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
Les cas de test intéressants et les crashs sont tous sauvegardés dans output_folder.
Amusez-vous bien.

Hé communauté open source, il y a beaucoup de choses à faire si quelqu'un veut contribuer.
Si vous avez des doutes sur l'une de ces fonctionnalités, n'hésitez pas à m'envoyer un message privé sur Twitter.
Pour les propositions de fonctionnalités, il y a la section Issues.
| -i DOSSIER | Dossier contenant les seeds initiales |
| -o DOSSIER | Dossier de sortie contenant les seeds intermédiaires et les crashs |
| -U | Connexion via USB |
| -spawn | Lancer et attacher au lieu de simplement attacher |
| -script SCRIPT | Nom du fichier script (par défaut fuzzer-agent.js) |