Fuddly: un framework de fuzzing et de manipulation de donnees
Author: Eric Lacombe
Date: 2015-06-03T07:30:12.121433+00:00
Publisher: STIC

Table des matières

1 Introduction
2 Présentation de fuddly
3 La modélisation des données
4 La manipulation des données
5 L'automatisation du processus de fuzzing
6 Conclusion et perspectives

Fuddly : un framework de fuzzing et de manipulation de données ?

Éric Lacombe
eric.lacombe@airbus.com
eric.lacombe@security-labs.org

Airbus Operations S.A.S.

Résumé fuddly est un framework de fuzzing et de manipulation de données. Il est actuellement utilisé dans le cadre de tests d'équipements avioniques qui mettent souvent en oeuvre des protocoles spéciques. D'autres formats de données et protocoles plus génériques ont également été testés dans ce contexte (JPG, PNG, ZIP, PDF et USB). Les principales caractéristiques de fuddly sont de permettre à l'utilisateur : de modéliser des formats de données très variés ; de les combiner entre eux ; de faciliter la mise en oeuvre de transformations complexes sur ces données ; d'autoriser la dissection de données existantes ; et d'allier des techniques de génération et de mutation. Enn, il fournit des moyens pour automatiser le processus de fuzzing en s'appuyant sur diérentes briques permettant de communiquer avec la cible, de suivre et d'observer son comportement, et d'agir en conséquence.

1 Introduction

L'expérience acquise sur le fuzzing d'équipements avioniques dans le cadre de notre travail, nous a poussé à développer notre propre framework de fuzzing. La raison à cela est que nous souhaitions laisser à l'utilisateur la possibilité : (1) de spécier des formats de données de façon plus exible que ce qui est permis au travers des autres frameworks (comme sulley ou Peach), et (2) d'eectuer des transformations de données plus élaborées. En outre, développer un nouveau framework fut considéré comme la solution la plus adaptée pour expérimenter de nouveaux concepts. De ce choix découle également une liberté totale quant à son évolution. fuddly est cette tentative visant à construire sur des concepts existants et à mettre en uvre nos idées, tout en restant compatible avec nos contraintes : pas de disponibilité du code source des cibles, architectures non-x86 (voire exotiques), moyens d'observabilité spéciques à l'avionique. [1]

Une vue d'ensemble de fuddly est donnée en section 2. La modélisation des données est ensuite abordée en section 3, avant d'introduire les manipulations permises sur ces données en section 4. L'automatisation du processus de fuzzing est alors présentée en section 5. Enn, les perspectives d'évolution envisagées sont examinées en section 6.

2 Présentation de fuddly

Notre framework de fuzzing et de manipulation de données est disponible sous licence GPL à l'adresse https://github.com/k0retux/fuddly. Il est écrit en python (compatible avec la version 2.7 jusqu'à la version 3.4) et peut être utilisé directement depuis un interpréteur python (comme ipython[2] ), ou bien depuis un shell dédié (simpliant certaines opérations). Ses principales caractéristiques sont de permettre à l'utilisateur :

1. de modéliser des formats de données très variés, qui :

- mêlent des représentations très nes pour certains aspects avec d'autres plus grossières, tout en orant la possibilité de les raner au besoin ;

- peuvent être combinés entre eux ;

- autorisent la dissection, de façon à manipuler facilement des données existantes ;

- permettent d'allier des techniques de génération de données avec des techniques de mutations ;

2. de faciliter la mise en uvre de transformations complexes sur les données modélisées. Nous entendons par complexe, la capacité d'agir sur n'importe quelle partie d'une donnée (composée d'éléments non nécessairement contiguës) tout en préservant la cohérence des dépendances, si l'utilisateur le souhaite. Cela revient à rendre possible des transformations articulées autour de critères syntaxiques (ex : altération d'une valeur entière en fonction de la taille du champ l'hébergeant) et sémantiques (ex : altération d'une valeur en fonction de sa signication pour un format ou protocole donné, altération d'un ensemble d'éléments d'une donnée formant un tout cohérent pour un format ou protocole donné) ;

3. d'automatiser le processus de fuzzing en s'appuyant sur diérentes briques permettant de communiquer avec la cible, de suivre et d'observer son comportement, et d'agir en conséquence (ex : dévier des exigences du protocole vis-à-vis du séquencement, des contraintes temporelles, etc.) en bénéciant de primitives de recherche et de transformation du modèle de données ; tout en consignant les diérentes informations générées lors de ce processus, et d'en permettre le rejeu.

3 La modélisation des données

La représentation des données est eectuée dans fuddly au travers de la description d'un graphe orienté acyclique, dont les nuds terminaux décrivent les diérentes parties d'un format de données, et les arcs (qui peuvent être de natures diérentes) capturent sa structure. Ce graphe intègre à la fois les informations syntaxiques et sémantiques sur le format de données. Dans la suite, nous appelons cette description de graphe un modèle de données. Une donnée particulière est alors appelée une instance de ce modèle. Le choix de cette modélisation permet de représenter avec exibilité des formats de données de nature très diérentes. Par exibilité, nous entendons d'une part la possibilité de modéliser de façon plus ou moins ne les diérentes parties d'un format (par exemple une modélisation ne sur des parties jugées plus complexe à traiter par la cible, et une modélisation grossière sur le reste), et d'autre part un niveau d'expressivité important.

À partir de ce modèle, nous pouvons générer des données et absorber des données existantes (projection d'une donnée existante dans le modèle de données). La génération de données autorise la création de données conformes au modèle si l'on souhaite interagir de façon correcte avec la cible ; ou la création de données dégénérées an d'éprouver la robustesse de la cible. L'absorption des données peut servir à générer des données à partir de données existantes lorsque la modélisation n'est pas assez ne pour générer des données susamment correctes par elles-mêmes ; ou encore de comprendre les sorties de la cible, an d'y répondre de façon adéquate ou non.

La génération de données revient à parcourir le graphe qui modélise le format de données. Après chaque parcours, une donnée est produite et chaque parcours fait évoluer le graphe, au choix, de façon déterministe ou arbitraire. Le parcours du graphe peut également être accompagné d'altération sur les nuds (cf. section 4). Diérents types de nuds ont été dénis pour la modélisation des données :

- Des nuds terminaux qui hébergent des variables typées (ex : UINT16, BitField, String, etc.).

- Des nuds non-terminaux qui dénissent la structure des données. Ils servent à ordonner les diérentes parties d'un format de données, et peuvent aller jusqu'à décrire une grammaire.

- Des nuds générateurs qui servent à générer dynamiquement une partie du graphe en fonction d'autres nuds (inclus ou non dans le graphe) et/ou d'autres critères, passés en paramètre.

La structure d'un format de données est capturée par les liaisons entre les nuds du graphe. Diérents type de liens se distinguent :

- les liens de parenté qui dénissent une structure de base entre les nuds du graphe. Ils sont régis par les nuds non-terminaux.

- les liens associés à des critères spéciques qui conditionnent des parties du graphe. Par exemple, la génération d'un nud spécique peut être associée à l'existence d'un autre, ou encore diérents ensembles de nuds peuvent être synchronisés sur leur cardinalité.

- les liens dénis entre les nuds générateurs et les nuds qu'ils prennent en paramètres. Ils sont notamment utiles dès lors qu'une relation évoluée existe entre plusieurs nuds. Les nuds générateurs servent alors à régir cette relation, en la dénissant au travers d'une fonction.

En outre, à chacun de ces nuds peut être associé des congurations alternatives (un nud terminal peut être changé dynamiquement en un nud non-terminal ou encore en générateur) qui peuvent être choisies dynamiquement, et même au cours du parcours du graphe. Cette fonctionnalité permet de capturer diérents aspects d'un format de données au sein d'un même modèle, tout en orant la possibilité de ne travailler que sur un seul aspect à la fois. Elle peut s'avérer utile également pour l'absorption. En eet, cette opération peut réclamer une modélisation diérente de certains aspects du format de données par rapport à la stratégie de génération. Les congurations alternatives des nuds rendent possible l'agrégation de ces diérences au sein d'un même modèle.

Enn, il est également possible d'associer (statiquement et dynamiquement) une sémantique aux nuds du graphe ou des méta-informations quelconques, rendant possible des altérations plus évoluées sur le modèle (cf. section 4).

4 La manipulation des données
fuddly dénit des primitives pour la manipulation des données modélisées. Certaines facilitent la recherche (sémantique ou syntaxique) au sein de cette donnée, d'autres servent à sa modication (aussi bien dans sa structure que dans son contenu), tout en laissant le choix à l'utilisateur de préserver les contraintes du modèle. Par exemple, la simple modication du contenu d'un chier dans une archive ZIP, modélisée dans fuddly, se résume à la modication d'un nud du graphe qui représente l'archive. L'ensemble des contraintes associées est ensuite recalculé automatiquement par fuddly (comme par exemple les champs compressed_size, crc, les osets des chiers suivants, etc.).

Les manipulations sur une donnée peuvent être mises en uvre au sein d'entités, appelées disrupteurs, briques de base dans l'automatisation du fuzzing. Un certain nombre de disrupteurs génériques, implémentés dans fuddly, sont applicables à n'importe quel modèle de données (ex : disrupteurs qui altèrent les nuds à variables typées ; itèrent sur les congurations alternatives des nuds ; tronquent les données ; autorisent l'appel à des outils externes pour modier les données ; etc.). D'autres sont par contre spéciques à un modèle en particulier.

Les disrupteurs génériques implémentés peuvent être paramétrés pour eectuer des modications suivant diérents critères (chemin dans le graphe, propriétés syntaxiques ou sémantiques, etc.). L'ordre du parcours peut également être aecté par des méta-informations éventuellement renseignées dans le modèle, comme le niveau d'intérêt des nuds (capturant l'intuition de l'évaluateur, quant à l'impact sur la cible, qu'entraînerait la modication de ces nuds). Parmi ces disrupteurs, certains conservent un état d'exécution d'un appel sur l'autre. Ils prennent en entrée, lors du premier appel, une donnée modélisée, et fournissent ensuite après chaque appel une nouvelle donnée issue de celle-ci. D'autres disrupteurs ne conservent aucun état. À partir d'une donnée fournie en entrée, ils produisent une nouvelle donnée unique.

Enn, concernant les disrupteurs à état, leur implémentation peut s'appuyer sur une infrastructure de parcours des données modélisées. Cette infrastructure met en uvre un algorithme paramétrable de parcours de graphe. À chaque étape de ce parcours l'algorithme fait appel à un objet visiteur-consommateur (fourni préalablement en paramètre). Ce dernier dispose alors de la possibilité de consulter le nud sur lequel il est appelé, d'eectuer autant de modications qu'il le souhaite (chaque modication entraînant la génération d'une nouvelle donnée), avant de redonner la main à l'algorithme de parcours. Cet algorithme pourra alors réévaluer le parcours du graphe suivant les modications engendrées (par exemple, si la modication a altéré un nud non-terminal, alors que l'algorithme venait de parcourir tous les nuds ls, il peut décider de parcourir à nouveau les nuds ls qui sont à présent peut être diérents).

5 L'automatisation du processus de fuzzing

L'automatisation du processus de fuzzing s'eectue dans fuddly à deux niveaux. D'une part, les disrupteurs peuvent être chaînés entre eux, qu'ils soient génériques ou spéciques, ou encore avec ou sans état. fuddly se charge de dérouler les opérations dans l'ordre demandés et d'alimenter les disrupteurs au besoin. D'autre part, le processus de fuzzing peut être implémenté au sein d'un opérateur virtuel, depuis lequel est réalisée la planication des opérations à eectuer sur la cible (type de données à envoyer, type de modications à appliquer avant l'envoi, etc.). L'opérateur est par défaut rappelé après chaque émission de données vers la cible, mais il peut également fournir un lot d'instructions à exécuter avant d'être rappelé. Cette approche autorise la stimulation simultanée d'une cible sur des entrées diérentes, chacune assujettie à un protocole spécique. Avant de décider de la marche à suivre, l'opérateur peut s'appuyer sur l'infrastructure de monitoring[3] de fuddly, pour déterminer l'état de la cible, ainsi que pour récupérer ses réponses.

6 Conclusion et perspectives

Dans ce papier, nous n'avons fait qu'eeurer les points saillants de fuddly. Bien que les fonctionnalités oertes par ce framework soient totalement utilisables, fuddly reste un terrain d'expérimentation, et au-delà de l'implémentation de nouveaux modèles de données, de nombreuses évolutions sont prévues, notamment :

- la dénition de nouveaux disrupteurs agissant sur des propriétés syntaxiques et sémantiques des modèles de données ;

- des fonctions génériques qui régissent des relations basiques entre nuds (longueur, compteur, etc.), utilisables directement par les nuds de type générateur ;

- l'intégration du DBI (Dynamic Binary Instrumentation) PIN de Intel [4]

dans l'infrastructure de monitoring, pour les cibles s'exécutant sur architecture x86 ;

- un nouveau type de nud permettant de dénir des parties d'un modèle sous forme de contraintes (programmation par contraintes via python-constraint[5] par exemple).

?. Une version étendue de l'article est disponible sur http://www.sstic.org.

1. Ces contraintes rendent dicile, voire impossible, l'utilisation de fuzzers s'appuyant sur des DBI comme Fuzzgrind ou Flayer. De même, les fuzzers qui instrumentent le code source comme american fuzzy lop sont exclus.

2. http://ipython.org/

3. L'infrastructure de monitoring autorise la mise en uvre de sondes indépendantes pour mesurer ou surveiller des paramètres quelconques liés ou non à la cible.

4. https://software.intel.com/en-_us/articles/pintool

5. http://labix.org/python-_constraint

Table of Contents

- Introduction
- Présentation de fuddly
- La modélisation des données
- La manipulation des données
- L'automatisation du processus de fuzzing
- Conclusion et perspectives
- ?
- 1
- 2
- 3
- 4
- 5