Restaurer des fichiers supprimés grâce à /proc

closeCet article a été publié il y a 9 ans 6 mois 20 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

J’avais prévenu lors du billet anniversaire, et donc aujourd’hui, les gens, j’attaque du « un peu plus » barbu. Désolé pour les non-linuxiens, j’ai rien à vous mettre sous la dent aujourd’hui, sauf si la sorcellerie vous attire; au pire la conclusion vous éclairera un peu plus sur mon amour pour Linux.

Lorsque vous supprimez par erreur un fichier ouvert par un programme, ou que vous supprimez le programme lui-même quand il est encore lancé, il est possible de restaurer ces fichiers depuis l’arborescence /proc. Voyons voir les deux cas. On parlera aussi vite fait de ce que ça implique d’un point de vue sécurité.

Rappel sur /proc

Contrairement aux autres « dossiers », /proc ne se trouve pas un sur système de fichiers « physique », mais en mémoire vive, et permet de décrire l’ensemble des données de processus tournant en mémoire vive. Si vous faites un ls -l /proc, vous verrez plusieurs dossiers numérotés ainsi que d’autres fichiers. Chaque dossier correspond à un processus, identifié par son PID (processus identifier). À l’intérieur de chaque dossier on retrouvera quantité d’informations, dont certaines vont nous être utile dans les situations que je vais vous présenter. Le contenu des dossiers est conséquent, je n’en parlerais pas plus ici, mais au fur et à mesure de ce que nous aurons besoin. Et ce ne sera que la surface de ce qu’il est possible de savoir avec /proc. Je vous laisse lire la (très) longue page de manuel qui accompagne souvent nos distributions.

Restaurer un fichier encore ouvert dans un programme

Vous êtes en train de regarder un film, pendant quelques minutes vous basculez sur une autre activité en mettant le film en pause (oh un SMS de machine !), vous allez manger un morceau, vous revenez, vous découvrez que vous n’avez pas assez de place pour terminer le téléchargement de l’iso de Manjaro XFCE en 64bit pour l’ordi d’un copain/d’une copine, et hop, en faisant le ménage vous supprimez le fameux film par erreur !

Pas de panique, vous pouvez « restaurer » le film en question tant que votre lecteur (dans mon cas, VLC) est ouvert. Première étape, on vérifie que le fichier est bien ouvert :

Donc, on constate bien que le fichier est absent du dossier, ce que confirme lsof (pour list open files), avec la mention (deleted) sur notre vidéo. On notera à la deuxième colonne le PID du processus. On va donc extraire des informations depuis le dossier /proc/4921, et en l’occurrence, on se concentrera sur le dossier /proc/4921/fd, qui contient les descripteurs de fichiers. Kézako ? Ce dossier recense tous les fichiers ouvert par le processus. regardons donc son contenu :

J’ai réduit l’affichage parce qu’il y a beaucoup de lignes, mais on le voit, ce ne sont pas des fichiers, seulement des liens vers ces fichiers. D’ailleurs si vous tapez la commande lsof plus haut sans le grep ensuite, vous verrez l’intégralité des fichiers ouverts. fd inclut aussi les sockets et autres pipes. On voit donc ici la référence (le descripteur) au  fichier supprimé. Eh bien, pour le restaurer c’est finalement simple :

Pas besoin de vous rappeler à quoi sert file je pense, étant donné que j’ai déjà abordé la question il y a quelques temps.

Restaurer un exécutable supprimé

Je vais prendre un exécutable fait maison, mais la manipulation est valable pour tout le monde (tous les processus). Voici donc le programme horriblement compliqué qui sert d’exemple, sauvegardé dans le fichier hello.c :

Oui, c’est un Hello World qui attend 10000 secondes pour ensuite s’arrêter. Programme C oblige, je vais d’abord le compiler, puis le lancer en tâche de fond, le supprimer, et enfin voir s’il est toujours là :

Pour le lancer, j’ai utilisé le caractère & à la fin pour le passer en tâche de fond. Ça permet de récupérer la main sur le shell. Notez qu’il vous indique alors avec quel PID le processus est lancé. On va donc logiquement regarder le dossier /proc/5417. Malheureusement, les descripteurs sont inutiles puisqu’ils ne concernent que les fichiers ouverts par le processus, mais ici, mon hello n’ouvre rien :

Par contre, il existe d’autres fichiers dans /proc/5417, dont un qui va fortement nous intéresser :

Pareil, j’ai réduit les infos, mais vous pouvez tester par vous-même pour constater l’étendue.  En particulier, on voit donc un lien « exe« , qui vous l’aurez compris indique le chemin vers l’exécutable, mais il indique que le fichier a été supprimé. On procède dès lors comme pour la vidéo, mais pour ce lien-là. On vérifie ensuite que la restauration s’est bien passée :

 Mon restored_hello fait la même taille que l’original supprimé, bingo !

Et si on parlait sécurité ?

Les mauvaises langues répondront que sous Windows, on ne peut pas supprimer un fichier ou un programme qui est ouvert/lancé, le système vous en empêche. C’est vrai. Mais du coup, si pour une raison ou une autre le verrou reste sur le fichier malgré la fermeture du processus associé (ou plus fréquemment, son plantage), vous l’avez dans l’os, et la plupart du temps, il faut redémarrer l’ordinateur pour libérer le fichier à supprimer. Et parfois, seul le recours à des logiciels tels qu’Unlocker permettra de s’en sortir, ce qui n’exclut pas l’obligation de redémarrage. Autant avoir le contrôle de votre machine, même si ça peut se faire au prix de bourdes. C’est plus souple, c’est mieux, bref, c’est Linux.

J’ai parlé de situations plutôt standards qui sont la plupart du temps provoquée par l’utilisateur. Mais on ne vit pas dans un monde de bisounours. Si je parle de sécurité, c’est de l’usage détourné de cette possibilité de supprimer un fichier/processus quand il est lancé. Un programme malveillant qui voudrait par exemple sniffer vos mots de passe, les stocker dans un fichier puis les envoyer au pirate pourrait se « cacher » de cette manière, il lui suffit de supprimer fichier et exécutable tant qu’il est lancé. Si votre premier réflexe est de couper le processus une fois découvert, vous détruisez définitivement par la même occasion toute trace de ce que faisait ce processus, et donc vous perdez les « preuves » qui vous auraient donné la possibilité de savoir ce qu’il faisait. Par la méthode présentée au dessus vous pouvez récupérer la quasi-intégralité de l’environnement d’exécution, ainsi que le programme lui-même, afin pourquoi pas de tenter une décompilation, un lancement en honeypot, une analyse à grand renfort de strace et de ltrace si vous avez le niveau. Bref, découvrir pourquoi il était là, ce qui pourrait permettre de savoir qui l’a mis là et comment, voir quand. Répond à ça, Windows !

Conclusion

Le noyau Linux est un outil magnifique, sur lequel vous pouvez avoir un très grand contrôle. Ici, on a utilisé le répertoire /proc dans un cas particulier, mais il regorge d’informations diverses et variées (faites un cat /proc/meminfo pour voir). Le répertoire /sys permet d’afficher et de modifier en temps réel des paramètres du noyau (utile par exemple dans le domaine de la gestion d’alimentation). /dev permet d’atteindre directement le matériel (souvenez vous dans l’épisode 4 de la migration, le chemin /dev/sdc vers la carte SD pour créer le médium d’installation de Manjaro). Bref, avec un noyau Linux, vous avez un plus grand contrôle sur le matériel et le logiciel. Ajoutez l’environnement GNU par dessus, et tout ce qui fait une distribution moderne, et vous avez une fusée, qui est il est vrai un peu plus compliquée à piloter, mais qui au moins ne vous empêche pas à tout prix d’atteindre la planète que vous souhaitez.