Le mois dernier a débarqué un thread sur bugtraq que j'ai trouvé assez intéressant et qui, chose rare pour cette ML, s'est étalé sur plus d'une semaine sans perdre en qualité dans les interventions. Je vous propose donc de résumer ici ce qui s'y est dit, vous allez voir c'est astucieux :)

Extrait d'un tableau de Vincent van Gogh - Domaine Public

Généralement sur un unixoïde, si vous avez des fichiers confidentiels à stocker, vous allez créer un répertoire, vous donner des droits dessus, retirer tous les droits pour le reste du monde, et enfin copier vos fichiers confidentiels dans ce répertoire. Les droits de votre dossier "secret" ressemblent donc à ça :

rwx------  2 toto toto 4.0K Nov  8 18:30 secret

Une fois le dossier "secret" sécurisé de la sorte les fichiers confidentiels créés dedans le sont généralement sans prendre garde aux droits qu'on leur attribue parce que, de toute façon, personne d'autre que vous ne peut lire le contenu du dossier "secret", et ne peut donc avoir accès à vos fichiers (car personne n'a pu avoir connaissance des inodes de vos fichiers). En effet quand bien même quelqu'un d'autre que vous connaitrai le chemin complet vers l'un de vos fichiers confidentiel toute tentative d'accès à ce fichier (et donc à l'inode correspondant) échouera lamentablement car la chaine de références à suivre pour obtenir le numéro de l'inode de votre fichier s'arrêtera, pour lui, au niveau du répertoire secret :)

C'est une méthode de contournement de ce type de cloisonnement qui a été abordé dans le thread de bugtraq dont je parlais en introduction et que nous allons voir ici. En effet dans certaines circonstances (assez particulières il faut bien l'avouer) Pavel Machek a trouvé une astuce permettant d'accéder à des fichiers sur lesquels on possède des droits, bien que l'on ne possède plus aucun droit sur une partie de l'arborescence menant à ce fichier. Alléchant non ?

D'abord voyons une méthode simple et connue comme le loup blanc pour parvenir à ce résultat : le hard link. Si jamais un hardlink existe entre /secret/himitsu.txt et /tmp/foo.txt n'importe qui avec les droits d'accès sur /tmp et sur /tmp/foo.txt aura accès à /secret/himitsu.txt. En effet un hardlink référence directement l'inode du fichier. En passant par le chemin /tmp/foo.txt vous avez donc directement accès au fichier sans aucun problème :) Par contre ça ne marche pas avec le symlink ! Les liens symboliques (ln -s) fonctionnent plutôt comme des raccourcis dans le monde de windows, c'est à dire que si /tmp/foo.txt est cette fois un lien symbolique vers /secret/himitsu.txt ce qui sera pointé par /tmp/foo.txt sera le chemin /secret/himitsu.txt et non pas le fichier en lui même, il faudra donc de toute façon résoudre le chemin /secret/himitsu.txt pour obtenir accès à l'inode du fichier, ce qui n'est pas possible si vous êtes bloqué au niveau du répertoire /secret

Si vous créez vos fichiers après avoir sécurisé le dossier /secret/ vous n'avez aucun souci à vous faire : personne n'a pu accéder un jour aux fichiers contenus dans le répertoire, et donc personne n'a pu créer de hard link vers ces fichiers (car personne n'a pu avoir connaissance de leur numéro d'inodes). En revanche le problème se pose si vous sécurisez l'accès au répertoire /secret/ après avoir créé les fichiers ! Par exemple si vous créez un répertoire /journal_intime et un fichier novembre2010 dedans, que vous fixez les permissions sur /journal_intime afin que personne d'autre que vous ne puisse accéder à ce répertoire, puis que vous vous mettez enfin à rédiger votre novembre2010 en toute quiétude=. Qu'est ce qui vous dit que quelqu'un n'a pas créé un hardlink vers /journal_intime/novembre2010 avant que vous ne coupiez les droits sur /journal_intime ? Et bien à priori rien ne vous le garantie et donc il est possible que vous rédigiez tranquillement novembre2010 alors que quelqu'un d'autre que vous y accède via un hardlink qu'il aura créé rapidement ! Pour parer ce cas de figure il y a une méthode simple : ls -l, le premier chiffre apparaissant après les permission représente le nombre de hardlink existant pour chaque fichier (attention : il est impossible de créer des hardlink sur des répertoires[1], ne tenez donc pas compte de ce chiffre sur les lignes correspondant à des répertoires). Par exemple ci-dessous on voit que novembre2010 a été compromis car quelqu'un a eu le temps de créer un hardlink vers lui, et que decembre2010 n'est, lui, bien référencé que par un hardlink (certainement parce qu'il a été créé en decembre, et que l'on a sécurisé le répertoire en novembre, donc avant sa création :) )

-rw-r--r--  2 toto toto 40.0K Nov  8 18:30 novembre2010
-rw-r--r--  1 toto toto 40.0K Nov  8 18:30 decembre2010

Grace à cette méthode toute simple de vérification du nombre de hardlink on aurait donc pu se croire à l'abri, mais ça aurait été sans compter sur le thread de bugtraq dont je parlais en introduction et qui apporte un raffinement amusant à la méthode de contournement de la protection par répertoire via hardlink.

Toute la méthode de Pavel se base en fait sur la présence du pseudo filesystem /proc (et ne fonctionne donc que sous linux). Quand Pavel a décrit son astuce sur Bugtraq il l'a présenté comme une faille de sécurité causée par /proc lui même sans beaucoup plus d'explication, et de là le débat est parti pour tenter d'expliquer plus précisément le phénomène observé. Je vais donc vous présenter directement les conclusions plutôt que tout le débat[2].

Ceci n'est pas une pipe - Creative Common by "focustoinfinity" on Flickr, from the painting by R.Magritte
Quand /proc est monté et qu'un process ouvre un fichier une entrée est automatiquement créée dans /proc/[PID]/fd/ et c'est là qu'un comportement contre-intuitif a lieu : bien que le répertoire se nomme "filedescriptor" l'entrée stockée n'est pas un filedescriptor mais un objet particulier au pseudofilesystem /proc. Là où ça devient amusant c'est que cet objet particulier se comporte comme un hardlink mais n'en est pas un ! Vous pouvez donc exploiter cette "astuce" dans un scénario complexe du type suivant :

  1. Alice crée un répertoire /secret avec des permissions qui autorisent Eve à y accéder
  2. Alice crée un fichier supersecret.txt dans le répertoire /secret avec des permissions quelconque qui autorisent Eve à y accéder en lecture seule
  3. Alice change les permissions de /secret pour que personne ne puisse y accéder à par elle
  4. Alice vérifie le nombre de Hardlink pointant sur le fichier supersecret.txt et constate qu'il n'y en a qu'un et que personne ne peux donc plus contourner la protection apportée par /secret
  5. Alice change, pour d'obscure raisons, les permissions de supersecret.txt pour que tout le monde puisse y accéder en lecture/écriture

Normalement Alice est tranquille : son fichier est innaccessible, et en tout cas impossible à modifier. Mais voilà : si Eve a ouvert le fichier avant qu'Alice coupe les permissions sur /secret Eve peut toujours lire le contenu de supersecret.txt mais il y a pire encore (c'est le comportement qui avait fait tiquer Pavel) : Eve peut modifier le contenu du fichier en ouvrant simplement l'entrée stockée sous /proc/[PID]/fd/[3] puisque cette entrée se comporte en fait exactement comme un hard link !

Amusant n'est-ce-pas ? Bon comme je vous avais prévenu c'est "exploitable" uniquement dans des contextes très très très particuliers, mais moi j'ai trouvé ça distrayant :-)

Notes

[1] Sauf sour MacOS10.5 me souffle-t-on à l'oreille...

[2] pour les détails menant à cette conclusion référez vous au thread original (vous trouverez un lien en début d'article)

[3] Pavel pensait qu'il s'agissait en fait d'un vrai "filedescriptor" et que /proc permettait de le ré-ouvrir, ce qui n'est en fait pas le cas