Le fuzzing est un outil de test logiciel qui consiste à injecter des données incorrectes pour rechercher des erreurs dans un programme, plus particulièrement dans le but de trouver des failles de sécurité. Aujourd'hui (en 2007), cette méthode est extrêmement efficace ! Disons que globalement, aucun programme ne résiste au fuzzing : ils finissent tous par montrer des faiblesses (qui se manifeste la plupart du temps par un plantage) dans un temps plus ou moins court.

Mon expérience du fuzzing

J'avais lu beaucoup de rapports de fuzzing montrant clairement de grosses faiblesses dans quasiment l'ensemble des logiciels testés. Mais je n'y croyais qu'à moitié, il fallait que je le vois de mes propres yeux. J'ai alors écrit un programme de fuzzing pour mon projet Hachoir. Durant deux semaines j'ai continuellement corrigé des bugs plus ou moins critiques. Comme quoi, la technique fonctionne très bien !

J'ai ensuite adapté mon programme de fuzzing pour tester d'autres applications. J'ai testé sur la suite Image Magick (manipulation de photos)... que je suis arrivé très rapidement à faire planter. J'ai isolé deux cas critiques : pour une image XCF de 80 Ko, Image Magick allouait 1 Go de mémoire (ce qui est énorme), et pour une image TGA, Image Magick consommait toute la puissance du processeur (100% du CPU) durant plusieurs minutes (je n'ai pas eu la patience de mesurer le temps exact). J'ai tenté de rapporter le bug mais je n'ai eu aucun retour.

Je me suis alors senti poussé des ailes et je me suis senti invinsible :-) Tant qu'à faire, allons tester un élément de sécurité ! J'ai choisi au pif l'anti-virus ClamAV... que j'ai réussi assez rapidement à mettre à genoux. Un document Word forgé prend 2 Go de disque dur et l'ensemble du processeur pendant plusieurs minutes. J'ai rapporté le bug qui a été classé comme critique et sera corrigé dans la prochaine version.

Écriture du programme de fuzzing

En pratique, pour Hachoir, Image Magick et ClamAV : je suis parti de fichiers valides (le format dépendant de l'outil testé) que j'ai ensuite tronqué et/ou j'y ai inséré des octets aléatoires. Je passe alors ce fichier forgé au programme testé. Cette algorithme est celui du programme « mangle.c » écrit par le belge Ilja van Sprundel que j'ai réécrit en Python. J'ai ensuite ajouté d'autres opérations comme modifier plusieurs octets à la fois, incrémenter/décrémenter un octet, insérer des valeurs spéciales, etc.

Ce qui me fait peur, c'est que globlament mon programme de test reste extrênement simple et pourtant j'arrive à faire planter très rapidement (moins de 5 minutes) tous les programmes que j'ai testés. Je n'ose même pas imaginer ce qu'on pourrait découvrir avec des programmes beaucoup plus intelligents. Et justement, l'été dernier des conférences ont présenté des logiciels de fuzzing utilisant des algorithmes génétiques ainsi qu'une grammaire dédiée au fuzzing. Le but étant, en gros, d'arriver le plus profondément possible dans le programme cible. Ils utilisent un débogueur dédié ainsi qu'un outil permettant de mesurer la couverture du code (quantité de code exécuté dans le programme cible).

Je pense qu'en couplant un fuzzing avec un outil comme Valgrind, on pourrait créer des outils beaucoup plus intelligents car on connaitrait la couverture du code mais également les erreurs d'accès mémoire.

Le fuzzing étant assez nouveau pour moi, je ne saurai conseiller un site web en particulier. En attendant, suivez les liens donnés sur la page Fuzzing de mon wiki. Je la ferai vivre au fur et à mesure des mes recherches.