Vous touchez à un point sensible ...
Historiquement , les ordinateurs étaient des mainframes où de nombreux utilisateurs distincts lancaient des sessions et traitaient sur le même machine physique. Les systèmes de type Unix (par exemple Linux), mais aussi VMS et ses proches (et cette famille comprend tous les Windows de la ligne NT, donc 2000, XP, Vista, 7, 8 ...), ont été structurés pour prendre en charge le modèle mainframe.
Ainsi, le matériel fournit des niveaux de privilèges . Un élément central du système d'exploitation est le noyau qui fonctionne au niveau de privilège le plus élevé (oui, je sais qu'il y a des subtilités en ce qui concerne la virtualisation) et gère les niveaux de privilège. Les applications s'exécutent à un niveau inférieur et sont empêchées de force par le noyau de lire ou d'écrire la mémoire de l'autre. Les applications obtiennent de la RAM par pages (généralement 4 ou 8 ko) à partir du noyau. Une application qui tente d'accéder à une page appartenant à une autre application est bloquée par le noyau, et sévèrement punie ("faute de segmentation", "faute de protection générale" ...).
Lorsqu'une application n'en a plus besoin une page (notamment à la fermeture de l'application), le noyau prend le contrôle de la page et peut la donner à un autre processus. Les systèmes d'exploitation modernes "vident" les pages avant de les rendre, où "effacement" signifie "remplissage avec des zéros". Cela empêche la fuite de données d'un processus à un autre. Notez que Windows 95/98 / Millenium n'a pas de pages vierges, et des fuites peuvent se produire ... mais ces systèmes d'exploitation étaient destinés à un seul utilisateur par machine.
Bien sûr, il existe des moyens d'échapper à la colère du noyau: quelques portes sont disponibles pour les applications qui ont "assez de privilèges" (pas le même genre de privilèges que ci-dessus). Sur un système Linux, il s'agit de ptrace (). Le noyau permet à un processus de lire et d'écrire la mémoire de l'autre, via ptrace (), à condition que les deux processus s'exécutent sous le même ID utilisateur, ou que le processus qui exécute ptrace () soit un processus "root". Une fonctionnalité similaire existe dans Windows.
Le fait est que les mots de passe dans la RAM ne sont pas plus sûrs que ce que le système d'exploitation autorise. Par définition, en stockant certaines données confidentielles dans la mémoire d'un processus, vous faites confiance au système d'exploitation pour ne pas le céder à des tiers. Le système d'exploitation est votre ami , car si le système d'exploitation est un ennemi, vous l'avez complètement perdu.
Vient maintenant la partie amusante. Depuis que le système d'exploitation impose une séparation des processus, de nombreuses personnes ont essayé de trouver des moyens de percer ces défenses. Et ils ont trouvé quelques choses intéressantes ...
-
La "RAM" que voient les applications n'est pas forcément une vraie "mémoire". Le noyau est un maître des illusions, et donne des pages qui n'existent pas forcément. L'illusion est maintenue en échangeant le contenu de la RAM avec un espace dédié sur le disque, où l'espace libre est présent en plus grandes quantités; cela s'appelle mémoire virtuelle. Les applications n'ont pas besoin d'en être conscient, car le noyau ramènera les pages en cas de besoin (mais, bien sûr, le disque est beaucoup plus lent que la RAM). Une conséquence malheureuse est que certaines données, prétendument conservées dans la RAM , arrivent sur un support physique où elles resteront jusqu'à ce qu'elles soient écrasées. En particulier, il y restera en cas de coupure de courant. Cela permet des attaques où le méchant attrape la machine et s'enfuit avec, pour inspecter les données plus tard. Des fuites peuvent également se produire lorsqu'une machine est mise hors service et vendue sur eBay et que l'administrateur système a oublié d'effacer le contenu du disque.
Linux fournit un système appelé mlock () qui empêche le noyau d'envoyer des pages spécifiques vers l'espace d'échange. Puisque le verrouillage des pages dans la RAM peut épuiser les ressources RAM disponibles pour d'autres processus, vous avez besoin de certains privilèges (root encore) pour utiliser cette fonction.
Une circonstance aggravante est qu'il n'est pas nécessairement facile de garder une trace de l'endroit où votre le mot de passe est vraiment dans la RAM. En tant que programmeur, vous accédez à la RAM grâce à l'abstraction fournie par le langage de programmation. En particulier, les langages de programmation qui utilisent Garbage Collection peuvent copier de manière transparente des objets dans la RAM (car cela aide vraiment pour de nombreux algorithmes GC). La plupart des langages de programmation sont donc impactés (ex: Java, C # /. NET, Javascript, PHP, ... la liste est presque infinie).
-
Hibernation ramène les mêmes problèmes, avec une vengeance. Par nature, l'hibernation doit écrire toute la RAM sur le disque - cela peut inclure des pages qui ont été verrouillées, et même le contenu des registres du processeur. Pour éviter les fuites dues à l'hibernation, vous devez recourir à des mesures drastiques comme le cryptage de l'ensemble du disque - cela implique naturellement de taper le mot de passe de déverrouillage chaque fois que vous réveillez la machine.
-
Le modèle mainframe suppose qu'il peut exécuter plusieurs processus hostiles les uns aux autres, tout en maintenant une paix et un isolement parfaits. Le matériel moderne rend cela très difficile. Lorsque deux processus s'exécutent sur le même processeur, ils partagent certaines ressources, y compris la mémoire cache; les accès à la mémoire sont beaucoup plus rapides dans le cache qu'ailleurs, mais la taille du cache est très limitée. Cela a été exploité pour récupérer des clés cryptographiques utilisées par un processus, à partir d'un autre. Des variantes ont été développées qui utilisent d'autres ressources de type cache, par ex. prédiction de branche dans un CPU. Alors que la recherche sur ce sujet se concentre sur les clés cryptographiques, qui sont des secrets de grande valeur , elle pourrait vraiment s'appliquer à n'importe quelle donnée.
De la même manière, les cartes vidéo peuvent faire un accès direct à la mémoire. Le fait que DMA ne puisse pas être abusé pour lire ou écrire de la mémoire à partir d'un autre processus dépend de la manière dont le matériel non documenté, les pilotes à source fermée et les noyaux collaborent pour appliquer les contrôles d'accès appropriés. Je ne parierais pas ma dernière chemise dessus ...
Conclusion: oui, quand vous stockez un mot de passe dans la RAM, vous faites confiance au système d'exploitation pour garder cela confidentiel. Oui, la tâche est difficile, voire presque impossible sur les systèmes modernes. Si certaines données sont hautement confidentielles, vous ne devriez vraiment pas utiliser le modèle mainframe et ne pas autoriser des entités potentiellement hostiles à exécuter leur code sur votre machine.
(Ce qui, au fait, signifie que des machines virtuelles hébergées et le cloud computing ne peut pas être sûr. Si vous êtes sérieux en matière de sécurité, utilisez du matériel dédié.)