dimanche, janvier 22 2012

Du capitalisme

L’Académie française propose une définition simple du capitalisme : le capitalisme est un « régime économique dans lequel les moyens de production sont propriété privée ». Dans la pratique, il est patent que le terme est loin d'être doté d'une acception consensuelle. D'où l'existence de nombreuses significations différentes, dont une se basant sur la mécanique d'accumulation du capital comme facteur de production.[1]

Billets de monopoly - Creative Common by graciepoo on Flickr
Dans l'acceptation du "capitalisme" telle qu'ébauchée en introdution de ce billet "l'accumulation du capital comme facteur de production" est l'un des fondamentaux, et en ce sens je suis un capitaliste de l'informatique. Cette réflexion m'est venu il y a déjà pas mal de temps en lisant une présentation (dont j'ai malheureusement oublié les références :( ) sur la façon de faire efficacement du fuzzing. Dans cette présentation il y avait un slide expliquant qu'écrire un fuzzer évolué n'était pas une bonne façon de faire du fuzzing, mais que la bonne façon de faire du fuzzing c'était d'écrire un fuzzer évolué pendant qu'un fuzzer écrit en 30s tournait. Ainsi, lorsque je me suis finalement mis à jouer un peu sérieusement avec de l'audit de code statique (environ un an après mes premiers tests dans le domaine) j'ai appliqué cette stratégie. Ce sont les premiers résultats de ces recherches que je vais relater dans ce billet.

Les outils

Adhérant totalement à la philosophie du "je travaille sur un bon outil pendant qu'un outil pourri que j'ai écrit en 10mn est déjà en train de tourner" j'ai donc commencé à analyser du code source PHP avec une dizaine de lignes de python qui se contentaient de :

  • Télécharger un projet PHP sur sourceforge/drupal/wordpress
  • Décompresser l'archive du projet
  • Faire l'équivalent d'un "grep" sur l'ensemble des fichiers PHP contenus dans l'archive
  • Effacer le repertoire temporaire dans lequel j'avais téléchargé et décompressé l'archive (ça a l'air con mais vu la simplicité du projet une fonctionnalité, même aussi triviale, compte).

Voilà quelques exemples des expressions régulières que ce mini script cherche:

  • (XSS) .*echo .*\$_GET.*
  • (XSS) .*echo .*\$_POST.*
  • (XSS) .*echo .*\$_REQUEST.*
  • (SQLi) .*SELECT .* FROM .* WHERE .* \$_GET.*
  • (SQLi) .*SELECT .* FROM .* WHERE .* \$_POST.*
  • (SQLi) .*SELECT .* FROM .* WHERE .* \$_REQUEST.*
  • ([LR]FI) .*require\(\$_GET.*
  • ...

Bref, cette première version était vraiment très rustique et pourrait être re-codé 100% en bash à coup de wget, unzip, et grep.

Pendant que cette première version tournait je me suis penché sur l'utilisation de PHC. L'idée est de réaliser ce dont je parlais dans mon vieux billet, à savoir d'utiliser PHC pour convertir le code source PHP en une représentation plus simple, et de réaliser une analyse par propagation de teinte sur cette représentation simplifiée. PHC propose 3 représentations intermédiaires, la plus simple d'entre elle étant la "MIR" c'est celle-ci que j'ai choisi (au format texte brute plutôt qu'XML) : phc --dump=mir mon_fichier.php.

Une fois mes fichiers PHP convertit en représentations "MIR" je parse le texte résultant pour en extraire des blocs de codes, chacun portant une étiquette utilisée par la représentation MIR pour d'éventuels GOTO, puis je débute ma simulation de propagation de teinte par la première ligne du premier bloc. A chaque assignation de variable rencontrée :

  • j'enregistre son nom dans un dictionnaire
  • je lui associe une valeur de teinte (si la variable se voit attribuée une constante la teinte est nulle, si elle se voit attribuée une variable de type $_GET[...] elle obtient une valeur de 1, si elle se voit attribuée la concaténation de deux autres variables sa teinte est la somme des teintes des variables concaténées, etc.)
  • je lui attribue une représentation (si son assignation est une constante je la reprend comme représentation, si son assignation est une variable sensible type "$_GET[...]" j'utilise ça, si on lui assigne la concaténation de variables je lui attribue la concaténation des représentation des variables concaténées, etc.)

Lorsqu'une fonction est appelée je regarde si son nom apparait dans l'une des listes de "fonctions sensibles" que j'ai hardcodé[2] et si tel est le cas je vérifie la teinte de la variable utilisée en argument. Si la teinte n'est pas nulle je lève une alerte en spécifiant la valeur de teinte utilisée, la représentation de la variable incriminée, et la famille de la fonction sensible (XSS, SQLi, [RL]Fi, PHPi).

Ce deuxième outil, bien qu'encore extrèmement rustique (246 lignes de python (199 sans les commentaires)), est sensiblement plus efficace que mon grossier "grep-like", comme nous allons voir tout de suite.

Les résultats

Ecrire un outil d'analyse de code c'est bien, mais encore faut-il avoir du code à analyser (et taper aléatoirement dans sourceforge c'est amusant deux secondes mais ça lasse vite) ! C'est donc en me demandant ce que j'allais bien pouvoir analyser que je me suis souvenu de cette liste de "bounty programs", et en particulier du dernier programme listé : celui de White Fir Design. Cette entreprise américaine, que je vous invite à découvrir, propose plusieurs bounty programs sur des logiciels open source dont un sur Wordpress et ses plugins téléchargés à plus d'un million d'exemplaires. C'est donc sur cette cible que j'ai testé mes deux outils d'analyse de code.

Pendant que j'écrivais mon outil de propagation de teinte basé sur PHC le premier script (grep-like) a relevé un nombre important d'alertes. C'est là que l'un des gros défaut de cette approche se fait sentir : il y a énormément de faux positifs. Par exemple la ligne suivante, bien que n'étant absolument pas vulnérable à quoi que ce soit, remonte à chaque itération de mon script comme un XSS potentiel :

echo (isset($_GET['session']) ) ? '?session=1' : '';

Malgré ces faux positifs j'ai tout de même réussi à confirmer quelques vulnérabilités de type XSS dans des pages d'admins de plugins téléchargés à plus d'un million d'exemplaire, et j'ai donc eu la double joie de toucher un petit bounty[3] tout en ayant le sentiment d'avoir rendu internet un peu plus sûr (tout ça avec "grep"...).

Une fois mon script d'analyse par propagation de teinte terminé je l'ai relancé sur le même périmètre et, après quelques réglages, j'ai eu le plaisir de voir qu'il parvenait à identifier l'ensemble des XSS que mon grep-like avait trouvé et que j'avais confirmé. Non seulement il obtient donc d'aussi bon résultats mais, en plus, le nombre de faux positif est nettement plus faible (la majorité de ceux qui restent sont dus à la non-prise en charge des fonctions de "sanitize-check" type "preg_match"...il faudra que je rajoute le support de ces vérifications à l'occasion). Enfin, cerise sur le gateau, la version par propagation de teinte a réussi à lever un lièvre que le "grep-like" n'aurai pas pu avoir (parce que plusieurs lignes de code étaient impliquées) : une jolie time-based-blind-SQLi.

En guise de conclusion sauvage qu'est-ce-qu'il y a à retirer de tout ça ?

  • que l'analyse statique de code, même dans ses versions les plus rustiques (grep) peut encore être utile de nos jours.
  • que l'approche consistant à faire tourner un outil pourri pendant que l'on travaille à la fabrication d'outils plus évolué est une bonne approche (en tout cas moi je l'aime bien, elle me donne l'impression que mon temps CPU est utile et, en remontant des résultats de temps en temps, elle me garde motivée sur le codage des outils performants et prépare les cas de tests sur lesquels on pourra tester les outils performants :) ).
  • que l'équipe de White Fir Design est impressionante (ces gars donnent de l'argent pour aider à sécuriser des logiciels dont ils ne retirent qu'indirectement profit, moi je trouve ça fort !)
  • que les développeurs de plugins Wordpress sont généralement très sympa (j'ai eu à chaque fois des retours très cools de leur part)
  • <troll>que le code de Drupal est plus sécurisé que celui de Wordpress</troll> (ou que mes outils lui sont moins adaptés et/ou que j'ai eu moins de chance avec Drupal qu'avec Wordpress).

Notes

[1] Toute l'intro est largement pompée de : http://fr.wikipedia.org/wiki/Capitalisme

[2] print,->get_var,->get_results, ->query, mysql_query, require, require_once, include, eval

[3] Bounty immédiatement dépensé sur eBay en composants électroniques divers et variés pour mon arduino

jeudi, décembre 2 2010

Man(i)on(s) des sources

Depuis quelques années le fuzzing a beaucoup fait parlé de lui, et il m'est d'ailleurs déjà arrivé de jouer un petit peu avec et d'y faire allusion sur ce blog. En revanche ce qui, d'après ce que je perçois, est complètement passé de mode c'est l'analyse de code source. Trouvant ça bien dommage je me suis penché sur ce qui existait pour analyser du code PHP...

Sleepy Pixy - Creative Common by "Alkan de Beaumont Chaglar" on Flickr
D'abord soyons clair : ce que je cherche à identifier à partir de code source PHP ce sont exclusivement des failles de sécurité. En aucun cas je ne vais m'attacher à trouver de potentiels bugs (utilisation de variables non déclarées, ...) ou problèmes de performances ($variable++ à la place de ++$variable, ...). En résumé je recherche donc des LFI, des XSS, et des SQLi :)

J'ai ainsi farfouillé un petit peu le net à la recherche d'outils d'analyse de code source PHP qui répondrait à mes attentes et ce qui m'a semblé être la seule solution (Open Source) viable c'est pixy. Pixy est un petit soft codé en Java qui tente d'identifier des XSS et des SQLi grâce à une recherche par teinte[1] à partir de code source PHP.

Quelques téléchargements sur sourceforge et exploit-db plus loin en guise de tests j'identifie plusieurs points marquants de pixy :

  • Il y a peu de faux positif. Quand pixy repère quelque chose, c'est généralement vrai :)
  • pixy ne sait pas repérer les points d'entrées dans un projet PHP, on doit manuellement lui spécifier un à un les fichiers PHP à étudier (il se débrouille en revanche correctement avec les includes :)). Personnellement ça s'est fini avec un find -name *.php -exec ... ;-)
  • pixy n'est pas du tout compatible PHP5...et c'est bien dommage parce que l'écrasante majorité des softs PHP que l'on trouve de nos jours sont en PHP5
  • plus dommage encore : pixy n'est plus mis à jour depuis 2007 et il n'est pas prévu qu'il supporte PHP5 un jour...
  • pixy plante parfois souvent (mais c'est généralement à cause de fichiers en PHP5 :( )

Du coup j'ai poursuivi ma recherche et je suis tombé sur ce papier très sympa (et récent qui plus est) ! En gros il s'agit d'une étude de sécurisation des applis PHP de façon automatisé par analyse de code (bref : pile le sujet de ce billet) et les conclusions[2] en sont qu'il faut soit utiliser des applis propriétaires aux algorithme obscurs, soit utiliser pixy bien qu'il soit vieux/bancale et pas vraiment utilisable de façon sérieuse, soit se tourner vers l'avenir en espérant que quelqu'un fasse quelque chose basé par exemple sur PHC.

Qu'est-ce-que PHC pensez vous en ce moment ? C'est un compilateur de PHP. :) ...Si vous ne voyez pas le rapport avec la choucroute (après tout, transformer du PHP en exécutable et rechercher des vulns dans du code source PHP ce sont deux choses bien différentes) vous y verrez peut-être plus clair quand vous saurez que PHC est capable de transformer du code PHP en 3 autres types de représentations intermédiaires (AST, HIC et MIC) et qu'il peut sortir le code transformé (en AST, MIC, ou HIC) au format "texte" ou au format XML. Donc en utilisant PHC vous avez un outil capable de transformer un code source PHP en une représentation de langage plus abstraite, au format texte ou XML, que vous pouvez alors traiter beaucoup plus facilement dans le but d'y faire une recherche par teinte :) Bon, bien sur, ce n'est donc pas une solution "clef en main" d'analyse de sécurité d'applis PHP à partir des sources (puisqu'il faut en fait re-coder toute la recherche par teinte), mais c'est tout de même une base solide qui pourrait permettre d'élaborer un petit moteur d'analyse assez rapidement.

L'un d'entre vous se sent inspiré... ;) ? Bon bah en attendant je continuerai d'utiliser pixy ^_^

Notes

[1] Un peu comme ce que font d'autres personnes avec valgrind pur du code compilé.

[2] Conclusions TRES résumés par mes soins, je vous invite à lire le sujet original pour en avoir une vision plus complète