Blog Haypo

Aller au contenu | Aller au menu | Aller à la recherche

lundi 10 mars 2008

Comment réaliser un fuzzer ?

Après de dizaines de projets d'articles avortés (mort-nés), j'ai enfin réussi à en finir un ! C'est l'article « Comment réaliser un fuzzer ? » qui est publié dans le magazine de sécurité informatique MISC numéro 36 (mars/avril 2008). J'explique quels sont les points critiques lorsqu'on écrit un fuzzer : génération des données, surveiller la cible, auto-configuration du fuzzer, etc. Image de la première des six pages de l'article :

L'article parle indirectement de mon travail sur le projet Fusil. Un deuxième article plus pratique et dédié à Fusil devrait suivre dans le prochain MISC (reste à l'écrire...).

Je regrette d'avoir oublié la section remerciements à la fin de l'article. Alors je profite de ce blog pour remercier Sebastien Tricaud, Feth Arezki, Stéphane Marchesin et ceux que j'ai oublié pour leurs relectures attentives et leurs conseils avisés. Merci aussi à Anthony Carré pour m'avoir encouragé à écrire pour des magazines papiers :-)

Au passage, si vous êtes amateur de sécurité informatique mais que vous ne connaissez pas encore MISC, je vous en conseille la lecture. Le prix élevé de 8€ est à diviser par deux car c'est un bimensuel : ce qui donne 4€/mois. D'ailleurs, il faut deux bons mois pour digérer les articles souvent complexes ;-)

mardi 4 mars 2008

Scanneur de ports PortBunny

Comme je n'ai pas pu aller au 24th Chaos Communication Congress (fin décembre 2007), je me suis rabattu sur les vidéos publiées quelques temps après. J'ai beaucoup apprécié les vidéos « (2279) Deconstructing Xbox 360 security » et « (2131) Port scanning improved ». Je voudrais parler plus particulièrement de PortBunny, un nouveau scanneur de port qui a pour logo un lapin rose. Le diaporama de la présentation est disponible en ligne.

Lire la suite

Historique de la faille vmsplice()

Le chercheur en sécurité Wojciech Purczynski, employé par COSEINC et membre de l'association iSEC Security Research, a trouvé divers bugs dans l'appel système vmsplice() du noyau Linux. Cette fonction, introduite avec Linux 2.6.17, sert à envoyer des données de l'espace utilisateur vers l'espace noyau pour alimenter un pipe. Lire mon précédent billet sur l'évolution des entrées/sorties dans Linux pour les détails. Les développeurs noyau sont prévenus dès le 1er février. Cet article relate la publication, l'exploitation, puis la correction de ces failles.

Lire la suite

lundi 4 février 2008

Sécurité des réseaux sociaux

Les années 2003 et 2004 ont vu fleurir un grand nombre de réseaux sociaux : LinkedIn, MySpace, del.icio.us, Orkut, Facebook, Flickr, ... La popularité de ces sites Internet a rapidement explosé : le nombre de membres se compte en millions. MySpace comptait 100 millions de membres en juillet 2007. Malheureusement, la sécurité de ces réseaux est régulièrement ébranlée. Pour le passage à l'année 2004, Annalee Newitz publiait l'article Defenses lacking at social network sites sur SecurityFocus. Extrait : « Williams explained that "XSS is amazingly widespread. Plus, XSS vulnerabilities are easy to discover and exploit" ». Les problèmes sont donc connus depuis longtemps. Voyons ce qu'il en est aujourd'hui.

Collecte d'informations : attaque ciblé et revente d'informations

Il y a un mois, Mary Landesman écrivait que les utilisateurs de réseaux sociaux donnent des détails sur leur vie, amour, travail, et loisirs qu'ils n'oseraient jamais dévoiler à un étranger dans un bar. Ces informations sont extrêmement utiles pour une attaque ciblée. L'attaque typique en ingénierie sociale est l'hameçonnage : envoi d'un courriel demandant à la victime d'aller sur un site Internet imittant l'habillage du site connu, ebay ou paypal par exemple, où elle sera invitée à saisir son identifiant, mot de passe ou autres informations confidentielles.

Certains réseaux sociaux indiquent ouvertement qu'ils revendent vos informations à des sociétés. Facebook en est un exemple : la section « Vie privée : la récolte et la vente des informations personnelles à des entreprises privées » de l'article Facebook de Wikipédia est forte instructive.

Heise-security vous conseille de ne pas noter d'information critique réelle telle que votre date de naissance ou votre adresse : posez-vous la question « est-ce que je dirai ça à un passant dans la rue ou à mon patron ? » avant de poster n'importe quel contenu. Petite anecdote amusante : How Facebook Ended My Marriage. Un couple ayant décidé de retirer leur fiançaille de leur profil Facebook, parce que c'était trop personnel, a provoqué une petite tornade à travers le monde. Plusieurs amis ont compris que leur mariage était annulé, certains allant même jusqu'à transmettre l'information par blog interposé.

Infection des sites Internet des réseaux

Comme on pouvait s'y attendre, les sites Internet des différents réseaux sociaux sont régulièrement infectés dans le but de prendre le contrôle du profil des membres ou bien d'infecter l'ordinateur des membres.

Samy is my hero

Le premier ver qui a fait parler de lui est le ver Samy is my hero injecté dans MySpace en octobre 2005. Le ver inscrit la victime comme ami de Samy et ajoute le message « but most of all, samy is my hero » au profil de la victime. L'auteur, Samy, a d'ailleurs monté une page web dédiée au ver. MySpace se protégait en bloquant le mot « javascript », mais Samy a outrepassé cette protection en écrivant le mot javascript avec un retour à la ligne entre java et script. Le code HTML est de la forme :

<div id=mycode style="background: url('java
script:eval(document.all.mycode.expr)')" expr="EXPLOIT"></div>

Le ver n'exploite pas vraiment de vulnérabilité de MySpace, mais plutôt du navigateur web. Pour que le ver fonctionne, ce dernier doit interprèter le Javascript inscrit dans le style CSS. Or un style CSS n'est pas prévu pour ça et le navigateur ne devrait pas le faire. Le ver fonctionnait sous Internet Explorer (Windows), mais ne touchait pas les versions récentes de Safari (Mac OS X) par exemple.

Le ver infectant automatiquement les amis des victimes (effet boule de neige), Samy a réussi à récolter un million d'amis MySpace en seulement 18 heures.

Failles Flash et WMF

En juillet 2006, MySpace a subi deux nouvelles infections. La première utilise une vulnérabilité du greffon Flash qu'Adobe avait corrigé il y à peine une semaine, lire MySpace Attacked by Flash Worm et Myspace Hack spreading like wildfire: SPAIRLKAIFS (16 juillet 2006). Le ver injecte du code HTML de la forme suivante dans le profil MySpace de la victime et installe un spyware sur l'ordinateur de la victime :

<embed allowscriptaccess="never" src="http://i105.photobucket.com/albums/mff225/yrkblack/redirecft.swf">

Quatre jours plus tard (20 juillet 2006), une publicité pour le site « DeckOutYourDeck.com » utilise une vulnérabilité WMF de Windows. Un cheval de troie est alors utilisé pour pour installer ClickSpring, un logiciel qui affiche de la publicité. Selon le Washington Post, ClickSpring a été installé avec succès sur un peu plus d'un million d'ordinateurs.

Livre d'or Orkut

En décembre 2007, c'est le réseau Orkut qui est infecté par un ver Javascript. Selon Symantec, le ver a modifié le profil d'environ 700.000 membres en 24 heures. Il modifiait le livre d'or (guest book) pour y injecter un lien vers du code Javascript. Des courriels ont également été envoyés aux victimes pour les persuader de visiter des livres d'or infectés. Les victimes étaient aussi inscrites automatiquement dans la communauté « Infectados pelo Vírus do Orkut » (infecté par le virus Orkut, en portugais). Le javascript génère du code Flash à la volé pour exécuter du code malicieux sans que la victime ne s'en rende compte. Le ver était resteint à Orkut, l'ordinateur de la victime n'était pas infecté.

Widget Facebook

Facebook propose à ses membres d'ajouter des widgets Javascript à leur compte. Début janvier dernier, un widget verollé installait le spyware Zango sur l'ordinateur des visiteurs. Le widget utilisait une <iframe> qui pointait sur l'installeur de Zango.

Infection par bandeaux publicitaires

Quelques jours après Facebook, un serveur de bandeaux publicitaires distribue du code verrolé exploitant des vulnérabilités des navigateurs web pour infecter l'ordinateur de la victime. De nombreux sites sont touchés, en particulier : MySpace, Excite.com et Blick.ch. Les bandeaux publicitaires installent des chevaux de troie comme RBot, SDBot et Spybot.

Vulnérabilités des barres d'outil

Pour faciliter la navigation, certains réseaux sociaux proposent des extensions pour votre navigateur web. Malheureusement, chacun s'est vu attribuer une faille. Petite liste d'exploits milw0rm :

Second Life

L'univers Second Life n'est pas en reste. De plus en plus populaire, il intéresse également les pirates.

Le premier événement majeur date de novembre 2006 : un ver appelé Grey Goo installe des anneaux d'or dans l'univers. Le ver a beaucoup ralentit Second Life qui a du être mis hors service pour se débarasser du ver.

En septembre 2007, une faille a été trouvée dans le client Second Life. Elle utilisait le scheme « secondlife:// » dans une <iframe> pour voler l'identifiant et le mot de passe de la victime en réalisant une fausse authentification.

Plus drôle, des chercheurs ont démontré que la vulnérabilité Quicktime pouvait être exploité dans Second Life. Ils ont fabriqué une vidéo qui volait 12 Linden dollars (5 cents américains) et faisait dire à sa victime « I got hacked » !

Comment se protéger

Les attaques présentées dans cet article utilisent souvent de multiple vulnérabilités pour monter une attaque complexe : navigateur web, Javascript, Flash, QuickTime, etc. D'une manière générale, il faut s'assurer que tous les logiciels de votre ordinateur sont à jour. Avec une distribution Linux, c'est trivial, des outils sont déjà prévu pour ça. Sous Windows, vous pouvez par exemple utiliser le logiciel Personal Software Inspector de Secunia. N'utilisant pas Windows, je ne l'ai pas testé.

Pour la navigation sur Internet, je vous conseille d'utiliser Firefox plutôt qu'Internet Explorer. Firefox est le seul navigateur web a avoir une protection Javascript efficace : l'extension NoScript.

Conclusion

Comme nous avons pu le voir, les réseaux sociaux deviennent une cible de choix car ils offrent aux pirates un moyen d'infecter un million de membres et/ou d'ordinateurs en une seule journée. Les premières attaques étaient l'œuvre d'hackers voulant démontrer leurs capacités d'outrepasser les protections. Aujourd'hui, c'est un marché lucratif qui sert à installer de la publicité et chevaux de troie sur l'ordinateur des victimes.

De nombreuses sociétés travaillent main dans la main pour rendre le web plus sûr : consultez le site OWASP pour en savoir plus.

Une fois n'est pas coutume, je voudrais dédicasser ce billet à Florent ;-)

samedi 26 janvier 2008

Failles de sécurité liées à Unicode

La complexité du jeu de caractères Unicode est source de nombreuses failles de sécurité. Cet article présente quelques failles récentes pour illustrer les problèmes qu'on peut rencontrer.

Écriture bidirectionnelle (RLO et LRO)

Le premier type que je veux présenter n'est pas un bug d'Unicode, mais une fonctionalité ! On peut changer l'ordre dans lequel est écrit le texte. Un dieu du CSS, Stu Nicholls, l'utilise pour afficher son adresse email en clair, alors qu'en fait elle est écrite à l'envers dans la souce HTML ! Le style CSS est « unicode-bidi:bidi-override; direction: rtl; ».

Sauf que des malins ont pensé à utiliser cette fonctionnalité pour tromper l'œil humain en cachant l'extension d'un nom de fichier. L'article Deceptive file names under Vista (septembre 2007) montre comment une programme Windows (.scr) est affiché comme une image JPEG (.jpg) dans Windows Vista. Windows XP ne supporte pas cette fonctionnalité et affiche donc les codes de contrôle Right-to-left override (RLO, U+202E) et Left-to-right override (LRO, U+202D), montrant alors la supercherie.

Halfwidth and Fullwidth Forms

Les failles de type « directory traversal » outrepassent les mesures de sécurité et permettent de lire un fichier arbitraire. En PHP, on trouve souvent des failles du type « index.php?page=../../../../etc/passwd ». Les webmestres se protègent en interdisant la chaîne « ../ » dans le nom du fichier utilisé. Quelques fois, il est possible d'outrepasser cette protection en spécifiant le chemin complet du fichier. Une variante est de jouer entre les caractères « / » et « \ » selon le système d'exploitation. Certains serveurs et/ou systèmes d'exploitations acceptent également « .../ » dans le nom du fichier.

Ce type de bug est aujourd'hui connu et corrigé dans la majorité des serveurs. Dumoins, c'est ce qu'on pensait jusqu'à cette annonce : Unicode encoding can be used to bypass intrusion detection systems (juin 2007). L'idée est d'utiliser les caractères halfwidth et fullwidth de la plage Unicode U+FF01-U+FFEE. Le soucis est que les URL sont normalisées après avoir été validées !

Exemple de normalisation (décomposition canonique) avec Python 2.5 :

>>> from unicodedata import normalize
>>> char=normalize('NFKC', u'\uFF0E'); print "%r (%s)" % (char, ord(char))
u'.' (46)
>>> char=normalize('NFKC', u'\uFF0F'); print "%r (%s)" % (char, ord(char))
u'/' (47)
>>> char=normalize('NFKC', u'\uFF3C'); print "%r (%s)" % (char, ord(char))
u'\\' (92)

Séquence UTF-8 invalide

Il faut savoir que 7 ans plus tôt, un bug similaire avait déjà été découvert dans Microsoft IIS (octobre 2000). Cette fois-ci, le problème était la normalisation de l'encodage UTF-8. IIS était trop laxiste : il acceptait les séquences invalides, c'est-à-dire lorsqu'un code a une séquence plus longue en octets que la taille normale. Exemple : le caractère point « . » (U+2E) s'encode « 0x2E » en UTF-8, mais peut également être encodé (0xC0, 0xAE) (forme invalide).

Note : Le langage Java utilise d'ailleurs une forme non standard d'UTF-8 : le caractère nul est encodé volontairement (0xC0, 0x80) pour éviter qu'une chaîne soit tronqué par une fonction C bas niveau (telle que strcpy).

Confusion entre octet et caractère

Depuis que le jeu de caractères ASCII a été inventé, il existe une confusion entre la notion d'octet et de caractère. C'est encore plus vrai avec les jeux de caractères ISO-8859. La très grande majorité des programmes mélangent allègrement octets et caractères sans se poser de question. D'une manière générale, ce n'est pas trop gênant. On retrouve cette problématique lorsqu'on manipule du HTML : si on tronque du texte HTML à une position donnée, il est possible qu'on coupe en plein milieu d'une balise ou d'un caractère écrit sous la forme « &nom; ». Exemple : « J'ai mang&eacute; ! » tronqué au 12e caractère donne « J'ai mang&ea ».

Exemple de vulnérabilité : WordPress Charset SQL Injection Vulnerability (décembre 2007). Le problème apparait lorsque la base de donnée utilise un jeu de caractère chinois : Big5 ou GBK. La fonction qui échappe les chaînes de caractères SQL utilise addslashes() qui travaille sur des octets et non pas des caractères. La séquence d'octets (0xB3, 0x27) est alors échappée en (0xB3, 0x5C, 0x27). Or 0xB35C est un caractère valide en Big5, et on obtient donc une apostrophe seule !

Exemple avec Python 2.5 :

>>> user='\xB3\x27'
>>> sql=user.replace("'", "\\'")
>>> print unicode(sql, "big5")
許'

Le problème de fond est que PHP ne supporte pas Unicode. Il va falloir attendre PHP6 qui est en cours de gestation. Notez que ce genre de bug touche également les programmes écrit en C, Java ou même en Python. Bien que Python propose le type unicode, il est rarement utilisé bien que complet. Le module re (expression régulières) supporte les expressions unicode. Python 3000 vise, entre autre, à encourager l'adoption d'Unicode comme type par défaut des chaînes de caractères.

Autres bugs des implémentations d'Unicode

La bibliothèque Qt de Trolltech calculait mal la longueur des chaînes UTF-8 (il manquait un "+1") : Bugzilla Bug 269001: CVE-2007-4137 QT off by one buffer overflow (rapport de bug avec patchs pour Qt3 et Qt4, août 2007).

La fonction repr() du langage Python n'allouait pas assez de mémoire pour les chaînes Unicode : buffer overrun in repr() for unicode strings (août 2006, lire aussi le CVE-2006-4980). La fonction repr() n'allouait que 6 octets par caractère en ne considérant que la forme « \uXXXX », or la forme « \Uxxxxxxxx » peut être nécessaire et consomme 10 octets par caractère.

Conclusion

Unicode regorge de fonctionnalités qui sont souvent méconnues. Mal utilisées ou utilisées à mauvais escient, ça peut faire très mal. Je pense qu'il manque des fonctionalités de sécurité dans les bibliothèques Unicode. Les encodages non standards doivent être rejettés ou une alerte doit être déclanchée. Le module mod_security d'Apache propose ce genre de fonctionnalité : voir SecFilterCheckUnicodeEncoding et @validateUtf8Encoding. Il faudrait pouvoir désactiver toutes les fonctionalités Unicode et n'activer que ce dont on n'a besoin pour éviter les effets de bord indésirables.

vendredi 18 janvier 2008

Analyser un fichier binaire ou un programme inconnu

Cet article explique comment analyser un fichier d'origine peu sûre (ex: Internet) ou dont le format est inconnu (rétro-ingénierie). Il n'est sûrement pas exhaustif, mais liste divers outils bien pratiques pour ce genre de travail.

Avertissement

Lorsqu'on traite un fichier d'origine inconnue, il faut être sur ses gardes. Il se peut que le fichier attaque volontairement les outils d'analyse cités dans cet article. Les virus sont connus pour cracher les débogueurs et/ou changer leur propre comportement lorsqu'ils sont analysés. Travaillez sur une machine dédiée aux tests (ex: machine virtuelle), ou bien avec des privilèges minimaux (ex: machine coupée du réseau).

Détecter le type d'un fichier inconnu

Quand on reçoit un fichier binaire d'un type inconnu, le programme le plus utile est file. Il détermine le format du fichier à partir d'une importante base de signature. Il sait extraire certaines méta-données (dimension d'une image, version du format, etc.) et sait également faire la différence entre les sous-formats (tel que AVI ou WAVE pour le format RIFF, et Theora et Vorbis pour Ogg).

D'autres programmes peuvent servir pour identifier le format ou plutôt extraire les méta-données :

  • hachoir-metadata : supporte un grand nombre de formats de fichiers
  • extract : supporte un grand nombre de formats de fichiers
  • Kaa : images, sons et vidéos
  • identify : images, fait parti de l'excellente suite Image Magick

Analyse manuelle d'un fichier binaire

Le programme strings sert à extraire des chaînes de caractères d'un fichier binaire. Il vous faudra peut-être tester différentes options (encodages des chaînes) pour obtenir satisfaction. Souvent, strings donne beaucoup de faux positifs (la sortie est assez bruitée).

Un éditeur hexadécimal est toujours pratique pour rechercher visuellement des motifs, des chaînes de caractères, informations cachées, etc. J'utilise « hexdump -C fichier » ou bien khexedit (programme KDE).

Quand un fichier semble vraiment trop aléatoire, il se peut qu'il soit compressé et/ou chiffré. J'ai écrit un petit script « entropy.py » qui calcule l'entropie des symboles (mot de 8 bits) d'un fichier. Quelques exemples :

  • Programme EXE PE : 4,11 bits/symbole
  • Page HTML : 4,89 bits/symbole
  • Document PDF : 7,75 bits/symbole
  • Image JPEG et PNG : 7,87 et 7,82 bits/symbole
  • Archive gzip (.tar.gz) et bzip2 (.tar.bz2) : 7,99 bits/symbole

Au delà de 7,5 bits/symbole, il y a de fortes chances que le fichier contienne des champs compressés. C'est le cas dans les exemples, mais cet outil n'est qu'une mesure empirique.

Pour trouver les blocs compressés, une solution est de tenter de décompresser à partir du 1er octet, puis du 2e, etc. Le script « find_deflate.py » implémente justement cet algorithme, lent mais il fonctionne.

Enfin, l'outil hachoir-subfile permet de rechercher les fichiers contenu dans un fichier binaire en recherchant des motifs (marqueur de début, marqueur de fin) et en vérifiant que le fichier trouvé est valide (pour limiter les faux positifs). Il existe beaucoup d'outils similaires tels que Photorec et Scalpel, ou encore TestDisk et Sleuth Kit qui sont eux dédiés à l'analyse d'images de disque dur.

Analyse statique d'un programme

Ayant majoritairement travaillé sous Linux, je ne parlerai que des programmes ELF. L'outil objdump affiche de nombreuses informations sur un fichier ELF tel que ses sections, les symboles (objdump -T fichier) et sait désassembler du code. L'outil nm liste les symboles des bibliothèques statiques (extension du fichier « .a »). L'outil ldd liste les bibliothèques importés par un programme ou une bibliothèque avec le chemin complet qui sera utilisé. Enfin, elfsh est une suite complète d'outils pour l'analyse de fichier ELF.

Analyse dynamique

Analyser un programme sans l'exécuter ne permet que d'extraire de maigres informations. Il est toujours plus instructif de l'exécuter. Il existe de nombreux outils pour tracer un programme. strace affiche les appels systèmes. ltrace affiche les appels aux bibliothèques dynamiques, mais sait également tracer les appels systèmes. gdb est le grand classique parmis les débogueurs, boîte à tout faire.

Pendant l'exécution du programme, « lsof -p pid » affiche les fichiers qu'il a ouvert et « netstat » permet d'afficher les connexions réseaux.

Autres outils que je n'ai pas testé :

J'ai écrit un binding Python pour ptrace qui permet d'écrire facilement son propre outil d'audit à la manière de strace ou ltrace. Enfin, mon bref article Syscall contient mes divers notes sur les appels systèmes Linux.

Sites Internet

Pour en savoir plus sur le sujet, voici quelques sites très instructifs :

dimanche 2 décembre 2007

Bugs des générateurs de nombres pseudo-aléatoires

Maintenant que vous savez ce qu'est qu'un générateur de nombres pseudo-aléatoires, voyons en les bugs historiques, ainsi que les utilisations incorrectes qui en sont faites. Une mauvaise initialisation de la graine peut compromettre la sécurité de votre application. De même, la fonction rand() doit également être utilisée correctement sous peine d'abaisser l'entropie du résultat. Ce billet présente de multiple exemples dont le numéro de séquence TCP, pour finir sur les fuites d'information.

Lire la suite

Générateurs de nombres pseudo-aléatoires

Récemment, plusieurs vulnérabilités ont été trouvées dans des générateurs de nombre pseudo-aléatoires : Linux, Windows, FreeBSD et OpenSSL. Je prépare un billet dessus, mais avant je vais m'attarder sur les générateurs : comment un ordinateur purement déterministe pourrait être aléatoire ? Ce billet présente les algorithmes utilisés, comment mesurer la qualité d'un générateur, le groupe de travail du NIST, le choix de la graine et enfin les générateurs matériels.

Lire la suite

samedi 27 octobre 2007

Analyse statique de code et audit de sécurité

Alors que je cherchais un outil d'analyse statique pour PHP, j'étais tombé sur la page Tool Survey du projet Software Assurance Metrics And Tool Evaluation. Ce projet, mené par le NIST et financé par le DHS, m'intéresse car il vise à tester et classer divers outils servant pour un audit de sécurité. Plus particulièrement, la page Source Code Security Analyzers dresse une longue liste d'outils d'analyse statique de code.

Rien ne vaut une relecture manuelle et attentive

Je garde un souvenir amer de l'analyse statique. J'avais testé SPlint, FlawFinder et RATS pour m'aider à relire le code source du pare-feu NuFW écrit en C. Ces outils sont peu efficaces car on est rapidement noyés sous une tonne de faux positifs. On perd finalement plus de temps à affiner leur configuration qu'à trouver des bugs. Je préfère encore une relecture manuelle et attentive du code.

Quand les ressources humaines sont insuffisantes pour relire toute la base de code, il faut choisir efficacement les portions de code à auditer. Il vaut mieux commencer par celles qui traitent les données venant de l'utilisateur. Une autre approche est de rechercher des erreurs classiques comme les dépassements de tampon, erreur de formatage printf, injection SQL, etc. Je vous conseille d'ailleurs d'aller lire les recommandations du CERT : Secure Coding Standards.

Trouver une erreur memset avec Google

On peut s'amuser à exploiter les moteurs de recherche de code pour trouver des failles connues : koders.com, krugle.com et Google codesearch. Seul Google codesearch supporte les expressions régulières, sans référence arrière malheureusement. On peut également trouver des mots de passe codés en dur et autres indiscrétions. C'est le moment de redécouvrir la Google Hacking Database pour vous donner des idées. Recherchons par exemple une utilisation incorrecte de la fonction memset() par l'inversion du 2e et 3e argument. Utilisez le motif suivant avec Google codesearch :

memset\([^,]+,[^,]+,\ *0\)

On trouve cette erreur dans divers projets dont certains très connus : OpenSSL, GnuPG, Prelude, Linux, Mozilla, Python, Parrot, Kaffe, aMule, µClibc, libgphoto2, ATI gatos, WINE, Blender, etc. Après vérification dans quelques projets (en particulier OpenSSL, GnuPG et Prelude !), l'erreur est corrigée dans la dernière version. Le fait qu'elle ait existé un temps prouve que de meilleurs outils d'analyse statique seraient utiles !

Autre exemple : erreur memcpy

L'instruction « memcpy(dest, source, sizeof(dest)); » est incorrecte quand dest est un pointeur. La taille copiée est celle du pointeur et non pas celles des données pointées ! Voici donc deux commandes pour rechercher des utilisations incorrectes des fonctions memcpy(), memmove(), strncpy(), g_memdup(), memset() et wmemset() :

find DOSSIER -name "*.c"|xargs egrep -H '(memcpy|memmove|strncpy|memset|g_memdup)\(([^,]+), .*sizeof\(\2\)\)'
find DOSSIER -name "*.c"|xargs egrep -H 'w?memset([^,]+,[^,]+, *0)'

Sauf que strncpy() (et ses voisines) peuvent fonctionner pour « strncpy(dest, source, sizeof(dest)); » quand dest n'est pas pas un pointeur mais un tableau de taille fixe comme « char buffer[256]; »...

Complexité McCabe d'une fonction

Pour finir, un ami (misc) m'a fait découvrir aujourd'hui l'outil pmccabe par le billet The Cyclomatic Horror From Outer Space. Ce programme sert à estimer la complexité d'une fonction sachant qu'une note supérieure à 50 indique une fonction « non testable (risque très élevé) ». Je me suis amusé à lancer pmccabe sur la GNU libc avec la commande :

rm /tmp/out; find . -name "*.c"|xargs pmccabe >>/tmp/out; sort -nr /tmp/out|head

Voici les pires fonctions :

  • 494 : scanf()
  • 230 : fnmatch()
  • 222 : strtod()
  • 200 : collate_read()
  • 197 : dl_main()
  • 175 : wordexp()

Dans les commentaires du blog, on apprend que gcc explose le record avec une fonction à plus de 1000. Une scéance de refactoring cuisse-abdo-fessier ne ferait pas de mal à la libc et à gcc...

mercredi 8 août 2007

Sécurité des systèmes virtualisés

La virtualisation est décidément à la mode. Niveau logiciel (libre) : QEMU, Xen, Bochs et VirtualBox offrent un large panel de possibilités. Niveau matériel, les microprocesseurs grand public gagnent des jeux d'instructions supplémentaires avec Intel VT (Virtualization Technology) et AMD-V (AMD Virtualization).

La virtualisation présente un intérêt en sécurité pour isoler les composants logiciels. C'est une alternative aux prisons logicielles existantes : chroot(*), BSD Jail, zones Solaris, etc.

Un nouveau moyen de protection attire forcément des hackers qui vont chercher à le contourner. Joanna Rutkowska a proposé en juin 2006 une technique appelée Blue Pill (la pillule bleue du film Matrix) qui permet d'être totalement invisible pour le système d'exploitation. En avril 2007, Rutkowska fonde la startup InvisibleThingsLab, et récemment le code source de Blue Pill est rendu disponible sur bluepillproject.org (vous y trouverez présentations et détails techniques). Lire également l'annonce par heise Security.

En février dernier, Tavis Ormandy, de l'équipe sécurité de Google, publie un papier sur la sécurité des hôtes virtualisés pour CanSecWest 2007. Il a trouvé plusieurs failles de sécurité comme par exemple dans la carte réseau de Bochs : NE2000 RX Frame Overflow (mai 2007). N'ayant pour l'instant que survollé le papier, j'ai cru comprendre qu'il a utilisé le fuzzing avec deux outils : crashme et iofuzz (écrit à l'occasion ?). Il va falloir que je les teste un de ces jours, ainsi qu'ioctlfuzz et syscallfuzz de la Digital Dwarf Society :-)

(*) chroot est une prison logicielle écrite pour des raisons pratiques et non pas pour répondre à une problématique de sécurité, il existe de nombreuses manières de s'en évader !

mercredi 6 juin 2007

Bilan du SSTIC 2007

Me voilà de retour de Rennes où j'étais avec 3 collègues « nupik ! » pour le SSTIC. Ces trois journées de conférences étaient denses en information et vraiment très intéressantes. J'ai été agréablement surpris de recevoir les actes sur papier dès notre arrivée : plus de 300 pages contenant les publications de toutes les conférences ! Ça va me permettre d'en savoir plus à tête reposée. Je vous présente les conférences qui m'ont le plus marqué.

Mercredi : authentification Windows

Aurélien Bordes nous a offert une excellente présentation des « Secrets d'authentification sous Windows ». Il a réussi à vulgariser des techniques et concepts obscurs de Windows. En résumé : même si les hashs LM ne sont plus stockés sur disque dur, ils persistent en mémoire ! On peut également s'authentifier uniquement en connaissant un hash. Et enfin, si j'ai bien compris : il suffit d'être administrateur sur sa machine pour réussir à passer administrateur sur tout le domaine Windows.

Ce qui est drôle, c'est qu'il a supposé pour commencer qu'on est administrateur de la machine. Comprendre : c'est tellement facile de passer admin sous Windows, que je ne donne pas la peine de vous montrer comment ! Effectivement, les exploits Windows pleuvent ! Sortez les parapluies (hop, petite réferrence cachée à la météo Bretonne où il ne pleut que sur les ....).

Mercredi : analyse de canaux cachés

Christophe Clavier m'a enfin éclairé sur les canaux cachés dans sa conférence « Attaques par analyse de canaux cachés et de fautes. Applications aux algorithmes à spécifications secrètes ». En enregistrant la consommation de courant d'une puce électronique et en la bombardant avec un laser (c'est Starwars !), il en extrait des informations juteuses. Il a montré qu'on peut reconnaître des motifs dans les mesures de courant et deviner quels bits (d'une clé privée RSA) sont à 0 ou à 1. Avec ses schémas ça semblait clair... mais n'empêche que l'unité était un cycle processeur : on travaille donc à l'échelle de la nanoseconde !

Jeudi : fuzzing wifi

Alors que je n'avais pas terminé ma nuit, voilà que Laurent Butti et Julien Tinnès débarquent en parlant de « Recherche de vulnérabilités dans les drivers 802.11 par techniques de fuzzing ». Wow, je suis tout à vous les gars ! Toady m'avait déjà passé la présentation la semaine précédente, mais c'était bien plus clair avec les explications.

Je pense que tout le monde a été bluffé dans la salle lors de la démo : avec quelques paquets wifi, un exploit noyau est installé sans faire tomber le pilote wifi... alors qu'il utilise justement un bug dans le pilote. Le pire est que l'exploit se fait lors de la première phase de connexion wifi : avant l'authentification ! S'insérer dans un noyau sans contact physique, ça laisse quand même songeur.

J'étais aussi heureux de voir le travail d'autres personnes sur le fuzzing. Comme quoi cette technique est très hype ;-)

Jeudi : Metasm

Yoann Guillot nous a présenté son framework Ruby « Metasm, l'assembleur ». Cette boîte à outil permet d'insérer du code dans un programme en cours de fonctionnement, d'assembler des blocs de code, de compiler en assembleur à la volée, et bien d'autres choses.

J'ai surtout retenu qu'on peut écrire des shellcodes en assembleur en laissant des « trous » dans le code : des variables qui seront remplacées à la compilation ! Metasploit 3, également écrit en Ruby, va se baser sur Metasm pour les shellcodes. Ce qui évitera les BLOBs (shellcodes binaires peu souples) et vilains hacks.

Jeudi : analyse de la mémoire vive

J'entend de plus en plus parler d'attaques « tout en mémoire ». Nicolas Ruff nous le confirme dans sa présentation « Autopsie d'une intrusion « tout en mémoire » sous Windows ». Il y détaille toutes les méthodes pour dumper la mémoire : firewire, fichier d'échange (swap), génération d'écran bleu de la mort, hibernation, reset physique de la carte mère, etc. J'étais surpris par l'idée d'un reset de la machine mais selon ses dires, la mémoire est inchangée même après 15 secondes hors tension ! On pourrait donc débrancher puis rebrancher le PC tout en conservant le contenu de la RAM. Il parle alors de système d'exploitation minimaliste (il ne faut pas écraser la RAM !) pour dumper la mémoire.

Après le dump, il faut analyser l'image. Il présente deux méthodes pour retrouver l'organisation de la mémoire : recherche du registre CR3 ou recherche de motifs en mémoire (ex: recherche des structures des processus). Ses travaux sont très prometteurs et de plus en plus d'outils sont disponibles.

Jeudi : projet Fusil

Durant les rump sessions, j'ai eu l'honneur de parler de mon projet Fusil : présentation Fusil en PDF. C'était un exercice de style pour arriver à tenir dans quatre minutes et pas une seconde de plus. J'étais frustré de ne pas avoir plus de temps, mais au final c'est vrai que c'est tout bénef' : les rumps ennuyeuses sont vites zappées et on peut en voir un plus grand nombre en un temps minimal ;-)

Vendredi : OpenDocument et OpenXML

Philippe Lagadec confirme mes craintes : sa présentation « Sécurité d'OpenDocument et Open XML (OpenOffice et MS Office 2007) » montre que les protections des macros dans OpenOffice et Microsoft Office sont inefficaces. La politique de sécurité est incohérente et il est facile de tromper l'utilisateur (Social Engineering en force !). J'ai appris qu'OpenOffice peut embarquer des documents OLE2 de n'importe quel type. C'est sûrement pour des raisons de compatibilité avec Microsoft Office (sic). Or il existe un objet OLE2 permettant de lancer une ligne de commande arbitraire.

Bilan

Je rentre du SSTIC la tête grosse comme une pastèque. Je vais devoir creuser tout ça pour en savoir plus.

À peine rentré du SSTIC, je fonce dormir chez un ami pour y préparer mes présentations Python car le lendemain (Samedi) j'attaque les Journées Python Francophones.

Merci encore à toady qui nous a évité de dormir sous les ponts la première nuit. Il nous a dépanné en nous acceptant dans sa chambre d'hôtel. Tout de suite, ça crée des liens :-D

mardi 5 juin 2007

Utilisation de la pile

La pile (stack en anglais) est un espace mémoire servant à stocker les arguments des fonctions et des données utilisées temporairement dans les fonctions. Il ne faut pas abuser de cette pile car sa taille est difficilement contrôlable, et surtout on n'a aucune garantie sur le comportement lorsqu'on en sort.

Ce billet présente les erreurs courantes d'utilisation de la pile, l'exploitation de ces erreurs pour injecter du code, les contre-mesures et enfin des conseils pour l'utiliser correctement.

Lire la suite

samedi 19 mai 2007

Tentative d'attaque de gettext

En cherchant des failles de sécurité, j'ai réalisé que je n'avais jamais pensé à Gettext (bibliothèque de traduction). Or la majorité des applications Linux l'utilisent. Gettext utilise un ensemble de fichier portant l'extension « .mo » (un fichier par langue) : les variables d'environement (LANGUAGE, LC_ALL et LANG) indiquant lequel choisir.

Réussite du fuzzing

J'ai tenté de fuzzer un fichier .mo et je suis rapidement arrivé à faire planter mon programme de test. J'ai alors contacté l'auteur de gettext, l'allemand Bruno Haible, qui m'a répondu en moins d'une heure ! Résumé de sa réponse : « This is known: The gettext routines (...) don't verify the integrity of .mo files. (...) Such a verification would not serve the purpose of a maximally efficient lookup of translations ». Traduction libre : « Le problème est connu, les routines gettext ne vérifient pas l'intégrité des fichiers .mo. Une telle vérification serait en contradiction avec le principe d'efficacité (vitesse) maximale de la traduction. »

Je peux comprendre ses raisons mais je reste perplexe. De plus, il ajoute « It is the duty of the distribution or system manager to ensure that the directories containing .mo files (...) are not world- nor group- writable. » que je traduis « C'est la responsabilité de la distribution [Linux] ou l'administraeur système de s'assurer que les dossiers contenant des fichiers .mo ne sont pas modifiables par les utilisateurs ».

Échec sur un programme suid

Je me suis alors mis en tête de lui prouver qu'il avait tord et que ses bugs pouvaient mettre à mal la politique de sécurité. J'ai d'abord réussi à utiliser un fichier .mo arbitraire avec une astuce : en donnant la valeur « ../../../../../tmp » à la variable d'environnement LANGUAGE, gettext va chercher le fichier mo dans « /tmp/LC_MESSAGES/ ». J'ai alors testé sur un programme suid (ie. lancé avec les droits d'administrateur) et là : ça ne marchait plus.... bizzare. J'ai creusé Internet avec Google et je suis tombé des articles montrant que des vulnérabilités avaient déjà été trouvées en 2000 et en 2003 au sujet de gettext : soucis avec la variable NLSPATH et soucis avec la variable LANG. J'avais déjà lu des informations à ce sujet en tombant sur la liste des variables d'environnement de la glibc qui énumère les variables proscrites pour un programme suid.

Raison de l'échec

Tétu comme un âne, je me suis mis à lire le code source de la glibc et je suis retombé sur NLSPATH : la constante UNSECURE_ENVVARS (définie dans sysdeps/generic/unsecvars.h) contient les variables interdites pour un programme suid. Mais nul part je ne lis LANGUAGE, LC_ALL ou LANG. D'ailleurs, je réalise que ces variables d'environnement ne sont pas supprimées pour un programme suid. Finalement, je réalise que c'est gettext qui possède une protection ! Bruno Haible avait oublié de m'en parler ;-) Dans intl/dcigettext.c, si __libc_enable_secure vaut 1 (cas d'un programme suid) les locales contenant le caractère « / » sont proscites. Et bien voilà, tout simplement !

Conclusion

Fausse alerte, gettext est troué mais ce n'est pas (trop) grave :-) D'autres personnes avaient constatées le problème avant moi.

Néanmois, la sécurité reste minimale : elle consiste à bloquer les attaques injectant un dossier dans une variable d'environnement. Et encore, uniquement pour les programmes suid. Les autres programmes sont donc vulnérables.

mardi 10 avril 2007

Sites internets sur la sécurité informatique

Alors que je tentais, comme tous les mois, de vider ma liste de « [liens] favoris », j'ai réalisé que j'avais accumulé pas mal de liens vers des sites de sécurité informatique. Bien que je ne me suis pas donné le temps de les parcourir en profondeur, ils semblent tous fort intéressants. Voici donc ma petite liste du moment.

Mois des bugs (« Month of xxx bugs ») :

Blogs (liens vers la catégorie sécurité) :

Sites d'actualités :

  • Security Focus : Articles d'actualité
  • frSIRT : Veille sur les dernières alertes de sécurités

À la quête du Programme Parfait

Alors que j'écrivais un fuzzer pour Hachoir, j'ai commencé à trouver de vilains bogues dans Python. Ce récit va vous amener aux frontières des tests logiciels.

L'objectif de mon fuzzer est de trouver un maximum de bogues pour que je puisse ensuite les corriger. Le principe de mon fuzzer est de partir d'un fichier valide, d'y injecter quelques octets aléatoires, puis de tenter d'utiliser ce fichier « verrolé ». Cette technique marche extrêment bien : voyez le fuzzer généraliste de sam pour vous en convaincre.

Lire la suite