Récupérer les mots de passe

De Wiki de Jordan LE NUFF
< Outillage‎ | Jenkins
Révision datée du 2 juin 2020 à 16:08 par Jordan (discussion | contributions) (Page créée avec « == Présentation == Cette page a pour objet de décrire comment récupérer un mot de passe stockés dans Jenkins. == Mise en œuvre == Procédure trouvée sur https://lo… »)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Sauter à la navigation Sauter à la recherche

Présentation

Cette page a pour objet de décrire comment récupérer un mot de passe stockés dans Jenkins.

Mise en œuvre

Procédure trouvée sur https://looselytyped.com/blog/2017/10/25/uncovering-passwords-in-jenkins/.

Point de départ

La première chose qui est nécessaire est d'avoir accès au serveur Jenkins lui-même.

Commencer par se connecter en SSH sur le serveur Jenkins et localiser le home directory ($JENKINS_HOME) de Jenkins avec la commande suivante :

grep jenkins /etc/passwd|awk -F: '{print $6}'

Ensuite, il faut déterminer où est stocké le mot de passe dans Jenkins. Jenkins utilise plusieurs emplacements différents pour stocker les informations d'identification, selon qu'elles sont au niveau du système ou spécifiques à un job. Quelques fichiers et répertoires qui stockent les informations d’identification sont :

  • $JENKINS_HOME/credentials.xml
    • Ce fichier est utilisé par le plugin Credentials utilise pour stocker les informations d'identification.
  • $JENKINS_HOME/jobs/
    • C'est le répertoire dans lequel Jenkins stocke tous les jobs qui ont été configurés, ainsi que leurs fichiers config.xml respectifs. Dans ces fichiers se trouveront toutes les informations d'identification qui ont été fournies dans le cadre de la configuration du job.
    • Par exemple, le plug-in Artifactory permet de remplacer les informations d'identification par défaut pour chaque job. De tels remplacements sont stockés dans la configuration des jobs et ils sont localisés (chiffrés bien entendu) ici.

Généralement, un grep dans $JENKINS_HOME avec le nom d'utilisateur dont on souhaite découvrir les informations d'identification est le moyen le plus rapide de déterminer où chercher.

Détermination de la classe utilisée pour le cryptage / décryptage

Une fois le fichier dans lequel rechercher à été trouvé, l'étape suivante consiste à déterminer comment déchiffrer le mot de passe. Heureusement, Jenkins stocke la quasi-totalité de sa configuration dans des fichiers XML. La visualisation du fichier peut donc se faire via un cat ou un less, ou simplement via un scp du fichier sur la machine locale et le lire avec un éditeur de texte.

Par exemple, si le nom d'utilisateur est jenkins-user@mycompany.com et que les informations d'identification recherchées sont effectivement stockées dans credentials.xml, le fichier peut contenir un extrait comme celui-ci :

<username>jenkins-user@mycompany.com</username>
<password>{AQAAABAAAAAgyqp9mI73xTYaYkaMRNolxwxR+X0qev7q6Hb3KcchbM9VA5ERj0RG1Nrl/aFw7haU}</password>
  • L'extrait de code peut être différent de celui de l'exemple, mais tant que le nom d'utilisateur correspond, cela signifie qu'on est au bon endroit.

La balise <password/> apparaît. Il reste donc à décrypter son contenu.

Remonter ensuite dans la hiérarchie des balises jusqu'à la rencontre d'une balise ressemblant à un nom de classe Java pleinement qualifié. Par exemple :

<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
  <scope>SYSTEM</scope>
  <id>5dc3bbe5-e5a6-496e-a616-199a207d8122</id>
  <description>This is a user</description>
  <username>jenkins-user@mycompany.com</username>
  <password>{AQAAABAAAAAQ5Qp/KX1Ibliy/23sM6e3Lepwa/OObLtGHC5svihnTr4=}</password>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>

Cela permet de connaître la classe que Jenkins instancie pour prendre en charge cette propriété.

Il faut donc maintenant trouver le code source et déterminer le mécanisme utilisé par cette classe pour chiffrer / déchiffrer le mot de passe. Utiliser un moteur de recherche pour trouver le code source. Dans ce cas précis, il suffit de chercher com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl.

Un rapide examen du code source fait ressortir ce constructeur :

@DataBoundConstructor
@SuppressWarnings("unused") // by stapler
public UsernamePasswordCredentialsImpl(@CheckForNull CredentialsScope scope,
                                       @CheckForNull String id, @CheckForNull String description,
                                       @CheckForNull String username, @CheckForNull String password) {
    super(scope, id, description);
    this.username = Util.fixNull(username);
    this.password = Secret.fromString(password);
}

Ainsi, com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl utilise hudson.util.Secret pour chiffrer le mot de passe. Lors de la recherche suivante, le code source hudson.util.Secrets indique à son tour une méthode de déchiffrement :

@CheckForNull
public static Secret decrypt(@CheckForNull String data) {
...
}

La classe est utilisée pour chiffrer / déchiffrer le mot de passe est donc Secret. Il faut ensuite découvrir comment l'utiliser. Il pourrait être possible d'essayer de simplifier l’implémentation et d’arriver en quelque sorte à l’exécuter de façon isolée, peut-être dans une classe de test avec une méthode principale, mais cela serait compliqué, surtout si cette classe a des dépendances sur d’autres classes.

Il est donc nécessaire d'avoir un environnement d'exécution où il sera possible charger cette classe, ainsi que toutes ses dépendances, et de simplement appeler hudson.util.Secret#déchiffrer en passant le mot de passe trouvé dans credentials.xml. Jenkins fourni cet environnement d'exécution.

Utiliser la console de script pour découvrir le mot de passe

Jenkins est livré avec une console de script qu'il est possible utiliser pour exécuter arbitrairement des scripts Groovy. Dans cette console, exécuter le code suivant permettra de révéler un mot de passe :

import hudson.util.Secret;

println Secret.decrypt("{AQAAABAAAAAQ5Qp/KX1Ibliy/23sM6e3Lepwa/OObLtGHC5svihnTr4=}");

// Résultat : jenkins

Le mot de passe est ainsi retrouvé.