
Dans cet article, nous ne parlerons pas de l'AFL classique lui-même, mais des utilitaires conçus pour lui et de ses modifications, qui, à notre avis, peuvent améliorer considérablement la qualité du fuzzing. Si vous voulez savoir comment booster AFL et comment trouver plus de vulnérabilités plus rapidement - continuez à lire!
Qu'est-ce que l'AFL et à quoi sert-il?
AFL est un fuzzer guidé par la couverture ou basé sur les commentaires. Plus d'informations sur ces concepts peuvent être trouvées dans un article sympa,
"Fuzzing: Art, Science, and Engineering" . Récapitulons les informations générales sur l'AFL:
- Il modifie le fichier exécutable pour découvrir comment il influence la couverture.
- Mute les données d'entrée pour maximiser la couverture.
- Répète l'étape précédente pour trouver où le programme plante.
- C'est très efficace, ce qui est prouvé par la pratique.
- C'est très simple à utiliser.
Voici une représentation graphique:

Si vous ne savez pas ce qu'est l'AFL, voici une liste de ressources utiles pour commencer:
- La page officielle du projet .
- afl-training - une courte introduction à AFL.
- afl-demo - une démo simple de programmes fuzzing C ++ avec AFL.
- afl-cve - une collection des vulnérabilités trouvées avec AFL (n'a pas été mise à jour depuis 2017).
- Ici, vous pouvez lire ce que AFL ajoute à un programme lors de sa construction.
- Quelques conseils utiles sur le fuzzing des applications réseau.
Au moment de la rédaction de cet article, la dernière version d'AFL était la
2.52b . Le Fuzzer est en développement actif, et avec le temps, certains développements secondaires sont incorporés dans la branche AFL principale et deviennent hors de propos. Aujourd'hui, nous pouvons nommer plusieurs outils accessoires utiles, qui sont répertoriés dans le chapitre suivant.
Compétition Rode0dayIl convient également de mentionner la compétition mensuelle
Rode0day - un événement où les fuzzers tentent de trouver le plus grand nombre de bogues avec moins de temps que leurs adversaires dans des corpus pré-créés avec et sans accès au code source. Dans sa nature, Rode0day est une bataille entre différentes modifications et fourches d'AFL.
Certains utilisateurs de l'AFL ont
noté que son auteur, Michal Zalewski, avait apparemment abandonné le projet depuis la date des dernières modifications au 5 novembre 2017. Cela pourrait être lié au fait qu'il quitte Google et travaille sur de nouveaux projets. Les utilisateurs ont donc commencé à créer eux-mêmes de nouveaux
correctifs pour la dernière version actuelle 2.52b.

Il existe également différentes variantes et dérivés d'AFL, ce qui permet de fuzzer Python, Go, Rust, OCaml, GCJ Java, les appels système du noyau ou même des machines virtuelles entières.
Outils accessoires
Pour ce chapitre, nous avons collecté divers scripts et outils pour AFL et les avons divisés en plusieurs catégories:
Traitement des plantages- afl-utils - un ensemble d'utilitaires pour le traitement / l'analyse automatique des plantages et la réduction du nombre de cas de test.
- afl-crash-analyzer - un autre analyseur de crash pour AFL.
- fuzzer-utils - un ensemble de scripts pour l'analyse des résultats.
- atriage - un outil de triage simple.
- afl-kit - afl-cmin sur Python.
- AFLize - un outil qui génère automatiquement des builds de paquets Debian adaptés à AFL.
- afl-fid - un ensemble d'outils pour travailler avec les données d'entrée.
Travailler avec la couverture du code- afl-cov - fournit des données conviviales sur la couverture.
- count-afl-calls - évaluation du ratio. Le script compte le nombre de blocs d'instrumentation dans le binaire.
- afl-sancov - est comme afl-cov mais utilise un désinfectant Clang.
- covnavi - un script pour couvrir le code et l'analyse par Cisco Talos Group.
- Passes LAF LLVM - quelque chose comme une collection de correctifs pour AFL qui modifient le code pour faciliter la recherche de branches par le fuzzer.
Quelques scripts pour minimiser les cas de test- afl-pytmin - un wrapper pour afl-tmin qui essaie d'accélérer le processus de minimisation du cas de test en utilisant de nombreux cœurs de processeur.
- afl-ddmin-mod - une variation de afl-tmin basée sur l'algorithme ddmin.
- halfempty - est un utilitaire rapide pour minimiser les cas de test par Tavis Ormandy basé sur la parallélisation.
Exécution distribuée- disfuzz-afl - fuzzing distribué pour AFL.
- AFLDFF - Cadre de fuzzing distribué AFL.
- afl-launch - un outil pour l'exécution de nombreuses instances AFL.
- afl-mèreship - gestion et exécution de nombreux fuzzers AFL synchronisés sur le cloud AWS.
- afl-in-the-cloud - un autre script pour exécuter AFL dans AWS.
- VU_BSc_project - test de fuzzing des bibliothèques open source avec libFuzzer et AFL.
Récemment, un très bon article a été publié intitulé
«Mise à l'échelle de l'AFL sur une machine à 256 threads» .
Déploiement, gestion, suivi, reporting- afl-other-arch - est un ensemble de correctifs et de scripts permettant d'ajouter facilement la prise en charge de diverses architectures non x86 pour AFL.
- afl-trivia - quelques petits scripts pour simplifier la gestion de l'AFL.
- afl-monitor - un script pour surveiller AFL.
- afl-manager - un serveur web sur Python pour gérer multi-afl.
- afl-tools - une image d'un docker avec afl-latest, afl-dyninst et Triforce-afl.
- afl-remote - un serveur Web pour la gestion à distance des instances AFL.
Modifications AFL
L'AFL a eu un impact très fort sur la communauté des chercheurs sur la vulnérabilité et sur le flou. Il n'est pas surprenant du tout qu'après un certain temps, les gens aient commencé à apporter des modifications inspirées de l'AFL d'origine. Jetons-y un œil. Dans différentes situations, chacune de ces modifications a ses propres avantages et inconvénients par rapport à l'AFL d'origine.
Presque tous les mods peuvent être trouvés sur
hub.docker.comPourquoi?
- Augmentez la vitesse et / ou la couverture du code
- Des algorithmes
- L'environnement
- Travailler sans code source
- Émulation de code
- Instrumentation de code
Modes de fonctionnement AFL par défautAvant de passer à l'examen des différentes modifications et fourches de l'AFL, nous devons parler de deux modes importants, qui avaient également été des modifications dans le passé mais ont finalement été incorporés. Ce sont Syzygy et Qemu.
Mode
Syzygy - est le mode de travail dans instrument.exe
instrument.exe --mode=afl --input-image=test.exe --output-image=test.instr.exe
Syzygy permet de réécrire statiquement les binaires PE32 avec AFL mais nécessite des symboles et un dev supplémentaire pour rendre le noyau WinAFL conscient.
Mode Qemu - son fonctionnement sous QEMU peut être vu dans
«Internals of AFL fuzzer - QEMU Instrumentation» . La prise en charge de l'utilisation des binaires avec QEMU a été ajoutée à l'AFL en amont dans la version 1.31b. Le mode AFL QEMU fonctionne avec les fonctionnalités supplémentaires de l'instrumentation binaire dans le moteur de traduction binaire qemu tcg (un minuscule générateur de code). Pour cela, AFL a un script de construction qemu, qui extrait les sources d'une certaine version de qemu (2.10.0), les met sur plusieurs petits correctifs et construit pour une architecture définie. Ensuite, un fichier appelé afl-qemu-trace est créé, qui est en fait un fichier d'émulation en mode utilisateur de (émulation uniquement des fichiers ELF exécutables) qemu-. Ainsi, il est possible d'utiliser le fuzzing avec rétroaction sur les binaires elf pour de nombreuses architectures différentes prises en charge par qemu. De plus, vous obtenez tous les outils AFL sympas, du moniteur avec des informations sur la session en cours à des trucs avancés comme afl-analyse. Mais vous obtenez également les limites de qemu. De plus, si un fichier est construit avec une chaîne d'outils utilisant des fonctionnalités SoC matérielles, ce qui lance le binaire et n'est pas pris en charge par qemu, le fuzzing sera interrompu dès qu'il y aura une instruction spécifique ou qu'un MMIO spécifique sera utilisé.
Voici une
autre fourchette intéressante du mode qemu, où la vitesse a été augmentée 3-4 fois avec l'instrumentation et l'encaissement du code TCG.
FourchesL'apparition des fourches d'AFL est d'abord liée aux changements et améliorations des algorithmes de l'AFL classique.
- pe-afl - Une modification pour fuzzer les fichiers PE qui n'ont pas de code source dans le système d'exploitation Windows. Pour son fonctionnement, le fuzzer analyse un programme cible avec IDA Pro et génère les informations pour l'instrumentation statique suivante. Une version instrumentée est ensuite floue avec AFL.
- afl-cygwin - est une tentative de portage de l'AFL classique vers Windows avec Cygwin. Malheureusement, il contient de nombreux bugs, il est très lent et son développement a été abandonné.
- AFLFast (étend AFL avec Power Schedules) - l'une des premières fourches AFL. Il a ajouté des heuristiques, qui lui permettent de parcourir plus de chemins en peu de temps.
- FairFuzz - une extension pour AFL, qui cible les branches rares.
- AFLGo - est une extension pour AFL destinée à accéder à certaines parties du code au lieu d'une couverture complète du programme. Il peut être utilisé pour tester des correctifs ou des fragments de code récemment ajoutés.
- PerfFuzz - une extension pour AFL, qui recherche des cas de test qui pourraient ralentir considérablement le programme.
- Pythia - est une extension pour AFL qui est destinée à prévoir à quel point il est difficile de trouver de nouveaux chemins.
- Angora - est l'un des derniers fuzzers, écrit sur la rouille. Il utilise de nouvelles stratégies de mutation et d'augmentation de la couverture.
- Neuzz - fuzzing avec des réseaux neuronaux.
- UnTracer-AFL - intégration de AFl avec UnTracer pour un traçage efficace.
- Qsym - Moteur d'exécution concolique pratique conçu pour le fuzzing hybride. Essentiellement, c'est un moteur d'exécution symbolique (les composants de base sont réalisés sous forme de plugin pour la broche Intel) qui, avec AFL, effectue un fuzz hybride. Il s'agit d'une étape dans l'évolution du fuzzing basé sur le feedback et appelle une discussion séparée. Son principal avantage est qu'il permet une exécution concolique relativement rapide. Cela est dû à l'exécution native des commandes sans représentation intermédiaire du code, des instantanés et de certaines heuristiques. Il utilise l'ancienne broche Intel (en raison de problèmes de prise en charge entre libz3 et d'autres DBT) et peut actuellement fonctionner avec les architectures elf x86 et x86_64.
- Superion - Greybox fuzzer, dont un avantage évident est qu'avec un programme instrumenté, il obtient également la spécification des données d'entrée en utilisant la grammaire ANTLR et ensuite effectue des mutations à l'aide de cette grammaire.
- AFLSmart - Un autre fuzzer Graybox. En entrée, il obtient la spécification des données d'entrée au format utilisé par le fuzzer Peach.
Il existe de nombreux articles de recherche dédiés à la mise en œuvre des nouvelles approches et techniques de fuzzing où l'AFL est modifié. Seuls les livres blancs sont disponibles, nous n'avons même pas pris la peine de les mentionner. Vous pouvez les rechercher sur Google si vous le souhaitez. Par exemple, certains des plus récents sont
CollAFL: Path Sensitive Fuzzing ,
EnFuzz ,
"Efficient approach to fuzzing interpreters" ,
ML for AFL.
Modifications basées sur Qemu- TriforceAFL - Fuzzing AFL / QEMU avec émulation complète d'un système. Une fourchette par nccgroup. Permet de flouiller l'ensemble du système d'exploitation en mode qemu. Il est réalisé avec une instruction spéciale (aflCall (0f 24)), qui a été ajoutée dans le processeur QEMU x64. Malheureusement, il n'est plus pris en charge; la dernière version d'AFL est 2.06b.
- TriforceLinuxSyscallFuzzer - le fuzzing des appels système Linux.
- afl-qai - un petit projet de démonstration avec QEMU Augmented Instrumentation (qai).
Une modification basée sur KLEEkleefl - pour générer des cas de test au moyen d'une exécution symbolique (très lent sur les gros programmes).
Une modification basée sur Unicornafl-unicorn - permet de fuzzer des fragments de code en les émulant sur
Unicorn Engine . Nous avons utilisé avec succès cette variation d'AFL dans notre pratique, sur les zones du code d'un certain RTOS, qui a été exécuté sur SOC, donc nous ne pouvions pas utiliser le mode QEMU. L'utilisation de cette modification est justifiée dans le cas où nous ne pouvons pas avoir de sources (nous ne pouvons pas construire un binaire autonome pour l'analyse de l'analyseur) et que le programme ne prend pas directement les données d'entrée (par exemple, les données est chiffré ou est un échantillon de signal comme dans un binaire CGC), alors nous pouvons inverser et trouver les fonctions-lieux supposées, où les données sont traitées dans un format convenant au flou. Il s'agit de la modification la plus générale / universelle de l'AFL, c'est-à-dire qu'elle permet de tout flou. Il est indépendant de l'architecture, des sources, du format des données d'entrée et du format binaire (l'exemple le plus frappant de bare-metal - juste des fragments de code de la mémoire du contrôleur). Le chercheur examine d'abord ce binaire et écrit un fuzzer, qui émule l'état à l'entrée de la procédure d'analyseur. Évidemment, contrairement à l'AFL, cela nécessite un certain examen du binaire. Pour le micrologiciel nu, comme le Wi-Fi ou la bande de base, il y a certains inconvénients que vous devez garder à l'esprit:
- Nous devons localiser le contrôle de la somme de contrôle.
- Gardez à l'esprit que l'état du fuzzer est un état de mémoire qui a été enregistré dans le vidage de la mémoire, ce qui peut empêcher le fuzzer d'accéder à certains chemins.
- Il n'y a pas d'assainissement des appels à la mémoire dynamique, mais cela peut être réalisé manuellement, et cela dépendra de RTOS (doit être recherché).
- L'interaction RTOS entre tâches n'est pas émulée, ce qui peut également empêcher de trouver certains chemins.
Un exemple de travail avec cette modification
«afl-unicorn: Fuzzing Arbitrary Binary Code» et
«afl-unicorn: Part 2 - Fuzzing the« Unfuzzable »» .
Avant de passer aux modifications basées sur les frameworks d'instrumentation binaire dynamique (DBI), n'oublions pas que la vitesse la plus élevée de ces frameworks est indiquée par DynamoRIO, Dynlnst et, enfin, PIN.
Modifications basées sur le code PIN- aflpin - AFL avec instrumentation PIN Intel.
- afl_pin_mode - une autre instrumentation AFL réalisée via Intel PIN.
- afl-pin - AFL avec PINtool.
- NaFl - Un clone (du noyau de base) de fuzzer AFL.
- PinAFL - l'auteur de cet outil a tenté de porter AFL sur Windows pour le flou des binaires déjà compilés. On dirait que cela a été fait du jour au lendemain juste pour le plaisir; le projet n'est jamais allé plus loin. Le référentiel n'a pas de sources, seulement des binaires compilés et des instructions de lancement. Nous ne savons pas sur quelle version d'AFL il est basé et il ne prend en charge que les applications 32 bits.
Comme vous pouvez le voir, il existe de nombreuses modifications différentes, mais elles ne sont pas très utiles dans la vie réelle.
Modifications basées sur Dyninstafl-dyninst - American Fuzzy Lop + Dyninst == AFL balckbox fuzzing. La particularité de cette version est que d'abord un programme recherché (sans le code source) est instrumenté statiquement (instrumentation binaire statique, réécriture binaire statique) avec Duninst, puis est flou avec l'AFL classique qui pense que le programme est construit avec afl- gcc / afl-g ++ / afl-as;) Par conséquent, il permet de travailler avec une très bonne productivité sans le code source - Il était à une vitesse de 0,25x par rapport à une compilation native. Il présente un avantage significatif par rapport à QEMU: il permet l'instrumentation de bibliothèques liées dynamiques, tandis que QEMU ne peut instrumenter que le fichier exécutable de base lié statiquement avec des bibliothèques. Malheureusement, maintenant, cela ne concerne que Linux. Pour la prise en charge de Windows, des modifications de Dyninst lui-même sont nécessaires, ce qui est en
cours .
Il y a encore un autre
fork avec une vitesse améliorée et certaines fonctionnalités (le support des architectures AARCH64 et PPC).
Modifications basées sur DynamoRIO- drAFL - AFl + DynamoRIO - fuzzing sans sources sous Linux.
- afl-dr - une autre implémentation basée sur DynamoRIO qui est très bien décrite sur Habr .
- afl-dynamorio - une modification de vanhauser-thc. Voici ce qu'il en dit: "exécuter AFL avec DynamoRIO lorsque afl-dyninst normal plante le mode binaire et qemu -Q n'est pas une option." Il prend en charge ARM et AARCH64. Concernant la productivité: DynamoRIO est environ 10 fois plus lent que Qemu, 25 fois plus lent que Dyninst, mais environ 10 fois plus rapide que Pintool.
- WinAFL - le plus célèbre des fourches AFL Windows. (DynamoRIO, également mode syzygy). Ce n'était qu'une question de temps pour que ce mod apparaisse parce que beaucoup voulaient essayer AFL sur Windows et l'appliquer à des applications sans sources. Actuellement, cet outil est activement amélioré, et indépendamment d'une base de code relativement obsolète d'AFL (2.43b lorsque cet article est écrit), il a aidé à trouver plusieurs vulnérabilités (CVE-2016-7212, CVE-2017-0073, CVE- 2017-0190, CVE-2017-11816). Les spécialistes de l'équipe Google Zero Project et de MSRC Vulnerabilities and Mitigations Team travaillent sur ce projet, nous pouvons donc espérer de nouveaux développements. Au lieu d'une instrumentation de temps de compilation, les développeurs ont utilisé une instrumentation dynamique (basée sur DynamoRIO), ce qui a considérablement ralenti l'exécution du logiciel analysé, mais la surcharge résultante (doublée) est comparable à celle de l'AFL classique en mode binaire. Ils ont également résolu le problème du lancement rapide du processus, après l'avoir appelé mode de fuzzing persistant; ils choisissent la fonction à fuzz (par le décalage à l'intérieur du fichier ou par le nom de la fonction présente dans la table d'exportation) et l'instrument pour qu'elle puisse être appelée dans le cycle, lançant ainsi plusieurs échantillons de données d'entrée sans redémarrer le processus. Un article a été publié récemment, décrivant comment les auteurs ont trouvé environ 50 vulnérabilités en environ 50 jours en utilisant WinAFL. Et peu de temps avant sa publication, le mode Intel PT avait été ajouté à WinAFL; detalis peut être trouvé ici .
Un lecteur avancé pourrait remarquer qu'il y a des modifications avec tous les cadres d'instrumentation populaires à l'exception de
Frida . La seule mention de l'utilisation de Frida avec AFL a été trouvée dans
"Chizpurfle: Un Fuzzer Android Gray-Box pour les personnalisations des services des fournisseurs .
" Une version d'AFL avec Frida est vraiment utile car Frida prend en charge plusieurs architectures RISC.
De nombreux chercheurs attendent également avec impatience la sortie du cadre DBI Scopio par le créateur de Capstone, Unicorn et Keystone. Sur la base de ce cadre, les auteurs ont déjà créé un fuzzer (Darko) et, selon eux, l'utilisent avec succès pour fuzz les appareils embarqués. Vous trouverez plus d'informations à ce sujet dans
«Digging Deep: Find 0days in Embedded Systems with Code Coverage Guided Fuzzing» .
Modifications, basées sur les caractéristiques matérielles du processeurEn ce qui concerne les modifications AFL avec la prise en charge des fonctionnalités matérielles du processeur, tout d'abord, il permet de fuzzer le code du noyau, et deuxièmement - il permet un fuzzing beaucoup plus rapide des applications sans le code source.
Et bien sûr, en ce qui concerne les fonctionnalités matérielles du processeur, nous sommes surtout intéressés par
Intel PT (Processor Tracing). Il est disponible à partir de la 6e génération de processeurs (environ, depuis 2015). Donc, pour pouvoir utiliser les fuzzers répertoriés ci-dessous, vous avez besoin d'un processeur prenant en charge Intel PT.
Conclusion
Comme vous pouvez le voir, le domaine des modifications AFL évolue activement. Pourtant, il y a de la place pour des expériences et des solutions créatives; vous pouvez créer une nouvelle modification utile et intéressante.
Merci de nous avoir lu et bonne chance avec le fuzzing!
Co-auteur: Nikita Knyzhov
preslerPS Merci à l'équipe du centre de recherche, sans qui cet article serait impossible.