Blog Haypo

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

samedi 19 mai 2007

Journées Python le 2 et 3 juin 2007 à Paris

L'AFPy organise pour la première année les Journées Python Francophones. Au programme : de nombreuses conférences de 9h à 17h (voir plus si on est motivé), consultez le programme complet .

Au début je n'avais pas prévu d'y aller : Strasbourg - Paris ça fait encore 4h de train même si « le TGV Est arrive »... le 10 juin. Mais comme je vais au SSTIC, je vais m'arrêter à Paris au retour. Le SSTIC, c'est 3 jours de conférences, du 30 mai au 1er Juin à Rennes, sur le thème de la sécurité. C'est ma boîte, INL, qui me paie l'inscription (environ 200€ de mémoire) et le voyage. J'y serai avec 3 collègues et vu le programme, ça risque d'être vraiment chouette. En plus, je ferai un présentation éclair (5 minutes) sur le fuzzing ;-)

Pour revenir aux Journées Python (qui elles sont gratuites), je vais également y faire présentations : « Projet Hachoir et bonnes pratiques » et « Automatisation des tests logiciels ». Hum, ça a l'air intéressant, mais il va falloir trouver du contenu pour tenir 25 minutes chaque fois :-) Je mettrais toutes mes présentations en ligne une fois qu'elles seront écrites.

Présentations Python qui me tentent bien :

  • TraitsUI pour développer des applications graphiques : j'en avais déjà entendu parler et ça semble très prometteur comme technologie
  • Atelier http://ipython.scipy.org/ : interpréteur Python intégrant un débogueur, la coloration syntaxique, un petit éditeur, etc.
  • Lightning Talks : On peut s'attendre à plein de trucs chouettes :-)
  • Python et visualisation 3D : La 3D m'a toujours attirée
  • Dr. Gumby, the brain specialist (IA avec SciPy) : Intelligence artificielle et SciPy, ça ne peut qu'être intéressant.

En fait, il y a un peu tout qui me tente et je suis sûr que j'aurai de bonnes surprises. Allez, viendez aux Journées Python ;-)

MISE A JOUR POST WEEK-END : Vous pouvez maintenant consulter ma présentation du projet Fusil (PDF) et mes présentations Python (HTML).

Raccourcis clavier

Les raccourcis clavier permettent d'exécuter des commandes sans toucher à la souris. On ne perd pas de temps avec des aller-retours entre le clavier et la souris. Par contre, ils sont souvent peu ou mal documentés et difficiles à mémoriser. En réalité, le plus souvent on n'en connait même pas leur existence ! En tout cas, je vous garantis que ça en vaut la chandelle !

Commençons avec le b.a.-ba, le copier-coller qui évite d'avoir à retaper le même texte :

  • Sélectionner le texte en maintenant la touche SHIFT puis en se déplaçant (avec les touches flêchées)
  • Copier le texte avec « CTRL+C » (notation courante pour dire : maintenez la touche CTRL puis appuyez sur C sans relacher la touche CTRL)
  • Se déplacer à l'endroit où l'on veut coller le texte (toujours avec les touches flêchées)
  • Coller le texte avec « CTRL+V »

Cette manipulation est devenue pratiquement universelle à travers tous les logiciels sur les divers systèmes d'exploitation. Sachez qu'il en existe des centaines d'autres ! Une voici une petite liste :

  • Se déplacer mot par mot : CTRL+droite ou CTRL+gauche
  • Aller au début/à la fin de la ligne ou du document : touche Début (habituellement au dessus de la touche Fin) / touche Fin
  • Se déplacer page par page : touche Page haut / Page bas
  • « Tout » sélectionner : CTRL+A
  • Zone de saisie suivante / précédente : TAB / SHIFT+TAB
  • Recherche un bout de texte : CTRL+F
  • Annuler la dernière action : CTRL+z
  • Ouvrir un fichier : CTRL+o

Certains raccourcis sont différents selon les applications ou bien ne sont pas disponibles. Il est plus sûr d'ouvrir le menu Fichier ou édition et consulter les raccourcis affichés à droite du texte.

Bash

  • Naviguer parmis l'historique des commandes : Haut / Bas
  • Début/fin de la ligne : CTRL+a / CTRL+e
  • Couper la fin de la ligne : CTRL+k
  • Couper le mot précédent : CTRL+w
  • Coller ce qui a été coupé : CTRL+y
  • Rechercher une commande tapée récemment : CTRL+s (ensuite CTRL+s / CTRL+r permet de naviguer parmis les résultats de la recherche)
  • Interrompre le programme courant : CTRL+z (la commande « fg » reprend l'exécution alors que la commande « bg » continue l'exécution en arrière plan)

Vim

Pour vim, reportez-vous à mon article Vi car la liste est longue :-)

Firefox et Konqueror

  • Site (page) précédent / suivant : ALT+gauche / ALT+droite
  • Ouvrir un nouvel onglet : CTRL+T
  • Passer à l'onglet suivant / précédent : CTRL+Page bas / CTRL+Page haut

KDE

  • Ouvrir le menu K : ALT+F1
  • Lancer une application : ALT+F2 (j'utilise uniquement ça au lieu du menu K)
  • Fermer une application : ALT+F4
  • Aller sur le N-ième bureau : CTRL+Fn (ex: CTRL+F2 pour le 2e bureau)
  • Lancer le programme listant les processus : CTRL+Echappe

Cet article est loin d'être exhaustif, mais j'espère qu'il vous a donné goût aux raccourcis et que vous en trouverez d'autres par vous même :-)

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.

lundi 14 mai 2007

Publication de deux vulnérabilités

Du fuzzing, toujours plus de fuzzing ! Plus je triture les programmes et plus je trouve de bugs. Je n'ai pas encore assez de recul pour dire si c'est positif ou non. En tout cas, je n'arrête pas de publier des rapports de bugs.

Un collègue m'a conseillé de contacter des organismes s'occupant de diffuser les vulnérabilités pour que tous les gens concernés soient au courant et prennent les dispositions nécessaires. Le premier, FrSIRT, m'a répondu en 2h et le second, Securina, en 4h. Chapeau ! Et après quelques échanges d'emails pour leur donner des détails, deux bulletins de sécurité ont été publiés :

Je ne suis pas peu fier de lire mon nom sur ces sites Internet :-) Le bug ClamAV (anti-virus libre pour Windows et Linux) est inquiétant car aucun nouvelle version n'a été publiée pour le corriger. Si ce bug est exploité, il peut rapidement mettre un serveur anti-virus hors-service : consommation massive de ressource processeur et de disque dur.

Je suis de plus en plus persuadé que tous les programmes sont bogués et qu'un certain nombre de bugs sont exploitables par des pirates informatiques. Ce n'est vraiment pas rassurant car tous les types de documents sont affectés. Pour ne citer que les plus courant : on peut planter un programme avec un simple document PDF voir même une image JPEG !

Je cherche et je rapporte les bugs pour contribuer au libre mais également pour éviter que des pirates le fassent à ma place et exploitent les bugs. Comme je n'aurai jamais le temps de tester tous les programmes, je pense plutôt à publier mes outils de test pour que d'autres poursuivent mon travail. J'ai déjà commencé par mettre en place un serveur Subversion ainsi qu'une plateforme Trac pour publier mon travail. Mon nouveau projet est hébergé sur mon serveur perso à l'adresse : fusil.hachoir.org. Consultez mon tableau de chasse : liste des bogues trouvés par la méthode du fuzzing.

lundi 7 mai 2007

Fuzzing de la glibc (printf)

Suite de mon initiation au fuzzing. J'ai continué des tests pour trouver toujours plus de bug. J'avais lu par-ci par-là que les programmes ont de très nombreux points d'entrée, pas uniquement le clavier et la souris. J'avais testé les fichiers, j'ai alors testé les variables d'environnement. J'ai d'abord écrit un script bash utilisant strace (puis ltrace) pour traquer les appels à getenv() (entre autres). À partir de la liste des variables, j'en tenté de faire planter les programmes en passant des valeurs invalides (grand nombre, très longue chaîne, etc.). Le premier programme à planter était dpkg avec « COLUMNS=10000000 dpkg -l ».

J'ai mis une bonne grosse semaine à isoler le bug. J'ai compris que le bug venait de vfprintf() mais je n'ai pas compris dans quel cas on pouvait le reproduire. J'ai isolé la chaîne de formatage : on peut alors reproduire le bug avec la fonction printf de bash ou /usr/bin/printf : « printf "%-1.25000000s" "Hello" ». En creusant encore plus, jusqu'à l'assembleur (on peut pas creuser plus profond :-)), j'ai isolé la ligne C qui posait problème. C'était un appel à mbstowcs() utilisant un tampon local de la forme « wchar_t ignore[prec]; », or prec vaut 25000000. En clair : la glibc tente d'allouer 25 Mo dans la pile alors qu'elle fait que 8 Mo et que Linux ne sait pas la faire grossir automatiquement (honte à lui). Je pensais justement que c'était un appel à alloca() mais je faisais fausse route. Conclusion : utilisez la pile avec parcimonie. Évitez absoluement la fonction alloca() et la notation C « type var[taille]; » où taille est supérieur de 4096 ou une variable contrôlable directement ou indirectement par l'utilisateur.

J'ai rapporté le bug et il a été corrigé en 48h par Ulrich Drepper (mainteneur de la libc). Encore une belle preuve de la réactivité des développeurs de logiciel libre.