Récupérer le compte Root sur RaspberryPi et similaires

Récupérer le compte Root sur RaspberryPi et similaires

Dernière mise à jour le 24 février 2025

Table des Matières

“Salut, l’ami ! Comment ça va ? Tu te souviens de ce petit projet que j’avais sur le CubieTruck? Je m’y suis remis. Mais c’est dommage, j’ai perdu mon mot de passe root… Je vais devoir tout recommencer. Tu te souviendrais du mot de passe idiot qu’on avait choisi ensemble par hasard ?”

Si seulement c’était le mot de passe du compte utilisateur, ce serait facile : se connecter en tant que root, changer le mot de passe pour l’utilisateur, terminé. Mais cette fois, qui va sauver le compte root ? Est-ce qu’il y aurait par hasard un compte rootroot ? Non. Mais ne vous inquiétez pas, nous allons tout de même pirater le compte root. Mais comment ? C’est Linux, c’est super sécurisé, c’est le compte root, j’ai choisi un mot de passe super sécurisé avec 50 bits d’entropie aléatoire… Peut-être. Mais presque n’importe quelle sécurité échoue une fois que le pirate a accès au matériel. Et aujourd’hui, nous sommes les pirates !

« Hacker » le matériel

Obtenons l’accès au “matériel” : débranchez la carte SD ! Ensuite, branchez-la sur votre propre système et montez la partition root de votre Pi quelque part, par exemple dans /tmp/Rasp. Dans ce document, je vais me concentrer sur la récupération du compte root sur une carte flash, mais la même technique fonctionnerait sur n’importe quelle machine où vous pouvez accéder à la partition root en dehors de son système d’origine. Cela signifie, par exemple, débrancher le disque dur principal et le brancher sur un autre ordinateur, ou démarrer sur le matériel une distribution live à partir de laquelle vous pouvez monter la partition root.

Quelques points de théorie. Pour ceux que cela n’intéresse pas, passez au paragraphe suivant. Sur un système Linux, le fichier /etc/passwd stocke les informations des comptes. Ce fichier contenait également les mots de passe il y a quelques années, mais ils sont dans le fichier /etc/shadow désormais. La raison est que les informations dans le fichier /etc/passwd sont nécessaires à de nombreux outils (très) courants, même ls, il n’est donc pas possible de refuser l’accès à ce fichier et il est en fin de compte accessible en lecture à tous les utilisateurs du système. Bien sûr, les mots de passe ne sont pas stockés en texte clair, mais cela affaiblit tout de même la sécurité car cela permet à quiconque sur le système de récupérer le hash et d’effectuer une attaque hors ligne, comme une attaque par force brute. C’est pourquoi les mots de passe sont aujourd’hui stockés dans un autre fichier, le /etc/shadow, qui n’est accessible qu’à des processus hautement privilégiés, c’est-à-dire root. L’ancien champ de mot de passe dans le /etc/passwd n’est maintenant plus qu’un “x”, indiquant au système de consulter le fichier /etc/shadow à la place.

Remplacer le mot de passe

Maintenant que la partition root est montée sur un système qui n’est pas le sien, le système de permissions d’origine qui empêcherait quelqu’un d’autre que root d’accéder et de modifier le fichier /etc/shadow ne s’applique plus. Certaines stratégies voudraient simplement vider le champ de mot de passe, permettant ainsi de se connecter au compte sans mot de passe. Mais d’après mon expérience, cela ne fonctionne pas sur les systèmes avec des politiques de protection récentes. Ne chatouillons pas trop le système, essayons de trouver quelque chose de plus élégant.

Tout d’abord, il existe une option --root pour l’utilitaire passwd, que vous pouvez théoriquement définir sur le point de montage du lecteur de stockage :

passwd -R /tmp/Rasp root

Mais dans mon cas, ça n’a pas du tout fonctionné. Peu importe, faisons exactement la même chose, mais manuellement. Avec un avantage supplémentaire : nous allons apprendre quelque chose dans le processus.

Dans le fichier /etc/shadow, les mots de passe sont hashés et salés (miam…). La méthode, le sel et le hash résultants sont tous stockés sous la forme $method_id$sel$hash. Nous n’allons pas déchiffrer le mot de passe, mais maintenant que nous avons accès au fichier, on peut changer ce hash pour être celui d’un nouveau mot de passe. Quelque chose qu’on ne va pas oublier ce coup-ci, si possible…

Après quelques recherches d’un petit outil pratique pour faire le travail, j’ai découvert que le meilleur était un simple script Python. Il suffit de démarrer une console Python et de taper :

$ python
Python 3.5.0 (default, Sep 20 2015, 11:28:25)
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
>>> crypt.crypt('cilyan.org', crypt.mksalt(crypt.METHOD_SHA512))
'$6$2uhsNKMqZ/OoEfd6$7ihU49hjdfxb1O82fd5Kh2gJAvzWvUvFXS.yA/Wk6y.dO8cO/MBMWpJ4fyIol9BUYph.9seJ7wb2TqCjaaNHc.'
>>>

Ci-dessus, 'cilyan.org' est notre nouveau mot de passe, et la chaîne résultante correspond exactement à ce que nous devons placer dans le fichier shadow dans le champ mot de passe (n’oubliez pas quand même d’enlever les guillemets). J’ai utilisé l’algorithme SHA512, qui devrait également être standard sur votre système.

Mise à jour le 24/02/2025

Une méthode simple et rapide pour obtenir notre mot de passe haché et salé, c’est d’utiliser openssl

openssl passwd -6

-6 précise d’utiliser l’algorithme SHA512. Vous pouvez vérifier la méthode standard de votre système comme suit :

grep ENCRYPT_METHOD /tmp/Rasp/etc/login.defs

Mais de toutes façons, la méthode utilisée est stockée dans la chaîne avec le sel et le hash, donc même si ce n’est pas la méthode par défaut, vous devriez pouvoir vous connecter. De plus, openssl ne sait pas (encore?) générer un hash yescrypt.

Remplacez le mot de passe dans le fichier shadow, sur la ligne du compte root, qui devrait maintenant ressembler à ceci :

root:$6$2uhsNKMqZ/OoEfd6$7ihU49hjdfxb1O82fd5Kh2gJAvzWvUvFXS.yA/Wk6y.dO8cO/MBMWpJ4fyIol9BUYph.9seJ7wb2TqCjaaNHc.:15735::::::

Et si vous êtes vraiment, vraiment paresseux, vous pouvez simplement copier la ligne ci-dessus, la coller dans votre fichier shadow, et vous connecter à votre Raspberry Pi en utilisant le mot de passe “cilyan.org” !

Articles Similaires

La semaine dernière, je préparais un rapport d’analyse de données avec Jupyter, Pandas et Matplotlib (pour ne citer que quelques briques de ce fabuleux framework). Une des figures contenait deux sous-graphiques : le second étant un agrandissement d’une région du premier. Pour bien illustrer cela et, au passage, montrer au fanclub MATLAB à quel point ils sont restés “so 90s”, j’ai décidé de tracer une flèche entre les deux sous-graphiques.

Lire la suite

SWIG est un générateur de code de glue (wrapper) capable de connecter des bibliothèques compilées à un tas de langages de script. Le processus est principalement automatique, mais pour gérer certains cas particuliers, il faut aider le générateur à faire les choses correctement. Dans ma bibliothèque, toutes les fonctions renvoient un entier, qui est un code d’erreur. Une fonction spéciale, suivant le même comportement que strerror_r, peut être utilisée pour récupérer la signification d’un code d’erreur particulier. C’est un mécanisme assez courant pour le code C. Mais ce n’est pas ainsi que fonctionnent les langages de script. Dans leur monde, les fonctions sont plutôt censées lever des exceptions.

Lire la suite

Rust est un langage de programmation système conçu pour offrir sécurité mémoire, performance et concurrence. Il le fait grâce à des fonctionnalités telles que l’ownership, le borrowing et les lifetimes, permettant d’assurer la sécurité mémoire dès la compilation sans nécessiter de ramasse-miettes. Cela rend Rust particulièrement adapté aux applications critiques en performance et à la programmation système, où la gestion manuelle de la mémoire est généralement nécessaire. Ses abstractions “à coût nul” garantissent que les fonctionnalités de haut niveau n’impliquent pas de surcharge à l’exécution, renforçant ainsi sa performance. Son modèle de concurrence est conçu pour être sûr et efficace, facilitant l’écriture de code concurrent sans les pièges habituels des race conditions.

Lire la suite