vendredi 15 avril 2011

Why plausible deniability sucks, at last

La cryptographie est le meilleur moyen de garantir la confidentialité des données. Depuis Kerckhoffs, nous savons que les algorithmes doivent être publics et que la sécurité du chiffre ne doit reposer que sur sa clé. Si cette clé est divulguée, alors les données sont révélées. Pour parer à la demande de divulgation de la clé, il est tentant de cacher le chiffré. Deux méthodes existent, la stéganographie, ou la plausible deniability. Le concept de plausible deniability a été popularisé par truecrypt bien qu'il soit généralisable à tout autre système de chiffrement moyennant conditions. Ce principe repose sur l'existence de deux clés permettant d'ouvrir le même fichier chiffré, chaque clé donnant accès à des documents différents. La force de la méthode, dont le nom dérive, s'appuye sur le fait qu'il est impossible à un attaquant de prouver qu'une seconde clé existe.

Cet article de blog va s'intéresser au fonctionnement de la plausible deniability et montrer qu'in fine, l'implémentation impose un usage très désagréable de la méthode. Tout d'abord sera expliqué comment la plausible deniability fonctionne, et comment deux clés peuvent ouvrir différemment le même fichier chiffré. Ensuite seront vus les détails d'implémentation afin d'éviter de dévoiler l'usage de la seconde clé. Enfin sera montré la faille de la méthode, et la manière inélégante de la contourner.

En préambule, quelques mots de vocabulaire (je reprends la terminologie de Truecrypt). Le container, ou container principal, est le fichier contenant les données. Ce fichier n'a pas d'en-tête spécifique, il est chiffré intégralement. Le premier container est généralement confondu avec le container principal. Les données du container principal ne sont accessibles que si l'on fournit la première clé. Tous les containers truecrypt contiennent un container principal. Container caché: ce terme définit le second container, caché dans le container principal. Un second mot de passe permet d'accéder à ses données.

1/Comment fonctionne la plausible deniability?/
Démarrons par quelques définitions avant de montrer comment la plausible deniability est mise en oeuvre: Un procédé de chiffrement moderne doit produire un résultat indiscernable d'un flux d'octet aléatoire. Un container doit être préalablement rempli de données aléatoires.
Et l'idée vient d'elle même: il est donc possible de faire cohabiter un second container s'il est suffisement loin du premier. Si on prend un livre blanc en exemple, il est possible d'écrire deux histoires, l'une démarrant page 0, et l'autre démarrant page 80. La connaissance de la page de démarrage permet d'accéder à l'une ou l'autre histoire. La plausible deniability fonctionne de la même manière, cf http://www.truecrypt.org/images/docs/hidden-volume.gif :
Cela fonctionne bien. Un attaquant ne pourra pas différencier les octets aléatoires de la fin du disque des octets chiffrés par le container caché. Quelques précautions d'usages sont nécessaires et découlent de la lecture de l'image ci-dessus. Le container caché sera toujours plus petit que le container principal. Le premier container ne devra pas contenir trop de données, en effet elles pourraient écraser les données du container caché. (Pour cette raison, truecrypt propose une protection du container caché lorsque l'on écrit dans le premier container; bien entendu, les deux mots de passes sont nécessaires :) ).

2/Quelles précautions d'usage?/
Quelques précautions s'imposent pour celui qui souhaiterait implémenter son système de plausible deniability. Nous allons en voir quatre.

2.1-Le procédé crypto
A partir du moment ou un attaquant est capable de différencier du chiffré de l'aléatoire, il sera capable de détecter l'existence du second container rendant la plausible deniability inefficace puisqu'il prouvera par la même l'existence de données non révélée par la fourniture du mot de passe du premier container.
Truecrypt utilise AES comme méthode de chiffrement qui est encore solide à l'heure actuelle. Et le jour ou quelqu'un sera capable de différencier un flux aléatoire d'un flux chiffré par AES, il suffira de changer de procédé de chiffrement.

2.2-Le filesystem
Dans le container, les données sont rangées à l'aide d'un filesystem. Certains filesystems ont des caractéritiques impropres à l'utilisation de la plausible deniability. Le filesystem par défaut de linux, extX, duplique de manière régulière des informations sur son emploi (superblock, tables d'inodes, etc..). Le container caché démarre à partir d'un certain seuil. Les données du container caché vont donc écraser les métadonnées du premier filesystem. Un attaquant peut donc vérifier l'état sain des métadonnées sur l'intégralité du container pour s'assurer qu'aucun container caché ne soit présent.

Truecrypt fait le choix d'imposer FAT comme filesystem du premier container lors de l'emploi de la plausible deniability. FAT est un filesystem très basique qui n'écrit des données qu'au début de son disque. Il n'y a donc pas de risques d'écrasement des métadonnées du premier filesystem par le container caché puisqu'il n'y en a pas.

2.3-Les sauvegardes

Un cas particulier se pose pour les sauvegardes. En effet, un attaquant peut alors étudier deux versions du container et regarder les blocs de données qui sont modifiés. La détection de changement de blocs permet de prouver facilement l'existence d'un container caché. En effet, les blocs chiffrés ne sont modifiés que si le clair change. Le container caché démarre à partir d'un certain seuil, ou offset. Les blocs modifiés par le container caché sont donc au delà de ce seuil, et bien au delà des données du premier container. Un attaquant peut dès lors prouver l'existence du container caché par différenciation. Pour reprendre l'exemple du livre, cela signifie qu'un attaquant sait qu'entre deux versions les pages 1 à 10 ont été modifiées, et les pages 80 à 85. Le mot de passe du premier container lui indique que les fichiers font bien la taille des 10 premières pages. D'où la question: d'où viennent les modifs des pages 80 à 85? Et de là, découle la révélation du container caché.

J'ai écrit un petit programme permettant de donner un aspect visuel à ces changements. Le principe en est le suivant: je XOR les octets de deux versions du container. Et je me sers du résultat pour en faire une image. Si les octets sont identiques, alors le résultat vaut 0 (et donc un pixel de couleur 000000: noir). Si les octets sont modifiés, alors un pixel est coloré. Ci-joint une image.
 Le premier bandeau chiffré du haut correspond à la modification des données du premier container. Le second bandeau prouve l'existence du container chiffré: ces octets n'ont aucune autre raison d'être modifiés que par l'existence d'ajout de données dans le container caché. Cela correspond de plus à mon container. J'avais réservé les 2/3 de l'espace pour mon container caché. Il démarre donc comme attendu au premier tiers du container principale.

Truecrypt propose une solution pour éviter cela: il suffit de créer un nouveau container à chaque sauvegarde et dupliquer les données qu'il contient (cf: http://www.truecrypt.org/docs/how-to-back-up-securely).
Une autre solution serait de ne jamais faire de sauvegardes. Mais je ne pense pas que cela soit acceptable en raison du risque de pertes de données (on peut en effet penser que ces données sont importantes puisqu'elles nécessitent une protection accrue).

2.4-Les autres précautions
Il faut bien entendu lire également http://www.truecrypt.org/docs/?s=security-requirements-and-precautions qui évoque deux points principaux selon moi: la sécurité physique pour éviter la modification du logiciel Truecrypt (n'oubliez pas que 6 lignes de codes sont suffisantes pour trojaniser Truecrypt..) et la manière d'éviter la duplication des blocs chiffrés pour que la détection du volume caché soit réalisable comme indiqué au chapitre au dessus. Ces précautions sont relativement contraignantes, mais sont nécessaires même pour l'emploi "classique" de truecrypt (c'est à dire sans plausible deniability).

3/Mais alors tout va bien?/
Et bien non, tout ne va pas bien :-)
Le ver est dans le fruit et dans les méthodes citées au dessus. Il est à peu près possible d'employer la plausible deniability de manière fiable, en faisant particulièrement attention aux sauvegardes. Et c'est précisément là ou le bât blesse.
Prenons comme hypothèse une personne qui "backup securely" ses containers truecrypt pour éviter que l'on détecte ses containers cachés. Plaçons nous désormais comme attaquant face à cette personne et posons lui la question suivante:
"pourquoi avez vous choisi de générer un nouveau container de zéro pour chaque sauvegarde?".
Et comme la seule et unique raison de générer un nouveau container pour chaque sauvegarde est de pouvoir camoufler l'usage d'un container caché, la méthode se retourne contre son utilisateur: en voulant cacher l'usage de ses containers cachés, il en démontre précisément l'existence!

Aux échecs, cela s'appelle un zugzwang: c'est à vous de jouer et tous les coups sont mauvais. Si vous utilisez la plausible deniability; vous vous mettez dans une situation désagréable ou soit vous êtes
détectable, soit vous ne faites aucune sauvegarde...

Moralité de l'histoire: il n'y en a pas.

7 commentaires:

  1. A ce sujet, mais ça ne mérite pas un nouveau post de blog, dropbox a souffert de quelques problèmes de sécurité. Comme toujours de nombreuses personnes ont dit "ranapété, utilisez un container truecrypt, ajoutez lui de la plausible deniability et tout va bien"

    Sauf que mettre un volume truecrypt dans dropbox, c'est précisément permettre à un attaquant d'avoir de multiples copies au cours du temps et donc de pouvoir vérifier les blocs qui changent au cours du temps et ainsi de dévoiler la plausible deniablity.

    RépondreSupprimer
  2. Ca me semble très léger, en effet pour que cette "faille" soit caduque il suffit d'empiler plusieurs conteneurs les uns dans les autres :
    - tu as un container clair avec des données que tu veux montrer à toute le monde.
    - tu as un container chiffré contenant un autre container :
    - un container clair avec des données privées que tu ne veux pas montrer à tout le monde mais légales (photos hot, documents de boulot, données bancaires, ect...)
    - un container chiffré contenant là les données que tu ne veux montrer à personne.

    On te pose la question ? Super t'es coincé : ils vont se farcir tes photos hot et tes relevés de compte.

    RépondreSupprimer
  3. Et non. Si je reprends l'exemple du livre, on va te poser les questions:
    -de la page 1 à la page 25 on voit les changements liés à la partie en clair, OK.
    -de la page 50 à 80 on voit des changements liés à la partie chiffrée dont tu donnes le mot de passe, OK.
    -de la page 120 à 130 on voit des changements qui ne correspondent ni au clair, ni au premier container chiffré. Et là, que répondre?

    RépondreSupprimer
  4. "-de la page 50 à 80 on voit des changements liés à la partie chiffrée dont tu donnes le mot de passe, OK.
    -de la page 120 à 130 on voit des changements qui ne correspondent ni au clair, ni au premier container chiffré. Et là, que répondre?"
    Mais pourquoi regarderaient ils en deux parties différentes la page 50 à 130 ? Ce n'est pour eux qu'une seule et unique partie... Au pire on mélange les deux parties physiquement sur le disque...

    RépondreSupprimer
  5. Pourquoi regarder en deux parties différentes les pages 50 à 130? Eh bien reprend l'image donnée dans le post... Ca saute aux yeux.

    Et quand à mélanger physiquement les deux parties sur le disque, expliques moi comment tu mets ça en oeuvre.

    RépondreSupprimer
  6. Heu en faisant comme windows avant (ou le fait encore, j'ai plus que des unix depuis un bail) en fragmentant à l'extreme ? En écrivant les blocs en désordre ?

    RépondreSupprimer
  7. La plausible deniability impose la FAT32 (et c'est un filesystem qui a plus de 10 ans, qui fragmente).

    Mais soit tu fragmentes dans les premières pages et la seconde zone reste détectable, soit tu remplis plus que la première zone et tu écrases ton container caché...

    Pour l'écriture des blocs dans le désordre, c'est une idée intéressante. Mais une fois de plus, comment la mets tu en oeuvre? Tu codes un driver spécial? OK, très bien. Mais lorsqu'on te demandera pourquoi tu as choisi d'utiliser ce driver, quelle réponse feras tu? Que c'est pour éviter qu'on trouve ton container caché, prouvant par la même son existence...

    RépondreSupprimer