Jenkins Security
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Jenkins est un outil qui offre une méthode simple pour établir un environnement de continuous integration ou continuous delivery (CI/CD) pour presque n'importe quelle combinaison de langages de programmation et de dépôts de code source en utilisant des pipelines. De plus, il automatise diverses tâches de développement routinières. Bien que Jenkins n'élimine pas le besoin de créer des scripts pour des étapes individuelles, il fournit un moyen plus rapide et plus robuste d'intégrer l'ensemble de la séquence d'outils de construction, de test et de déploiement que ce que l'on peut facilement construire manuellement.
Basic Jenkins InformationAfin de rechercher des pages Jenkins intéressantes sans authentification comme (/people ou /asynchPeople, cela liste les utilisateurs actuels) vous pouvez utiliser:
Vérifiez si vous pouvez exécuter des commandes sans avoir besoin d'authentification :
Sans identifiants, vous pouvez regarder à l'intérieur du chemin /asynchPeople/ ou /securityRealm/user/admin/search/index?q= pour noms d'utilisateur.
Vous pourrez peut-être obtenir la version de Jenkins à partir du chemin /oops ou /error.
Dans les informations de base, vous pouvez vérifier toutes les façons de se connecter à Jenkins :
Basic Jenkins InformationVous pourrez trouver des instances de Jenkins qui vous permettent de créer un compte et de vous y connecter. Aussi simple que cela.
De plus, si la fonctionnalité/plugins SSO étaient présents, vous devriez essayer de vous connecter à l'application en utilisant un compte test (c'est-à-dire, un test compte Github/Bitbucket). Astuce de ici.
Jenkins manque de politique de mot de passe et de mitigation de bruteforce de nom d'utilisateur. Il est essentiel de bruteforcer les utilisateurs puisque des mots de passe faibles ou des noms d'utilisateur comme mots de passe peuvent être utilisés, même des noms d'utilisateur inversés comme mots de passe.
Utilisez ce script python ou ce script powershell.
De nombreuses organisations combinent des systèmes de gestion de code source (SCM) basés sur le SaaS tels que GitHub ou GitLab avec une solution CI interne auto-hébergée comme Jenkins ou TeamCity. Cette configuration permet aux systèmes CI de recevoir des événements webhook des fournisseurs de SCM SaaS, principalement pour déclencher des travaux de pipeline.
Pour ce faire, les organisations mettent en liste blanche les plages IP des plateformes SCM, leur permettant d'accéder au système CI interne via des webhooks. Cependant, il est important de noter que quiconque peut créer un compte sur GitHub ou GitLab et le configurer pour déclencher un webhook, envoyant potentiellement des requêtes au système CI interne.
Dans ces scénarios, nous allons supposer que vous avez un compte valide pour accéder à Jenkins.
Selon le mécanisme d'autorisation configuré dans Jenkins et les permissions de l'utilisateur compromis, vous pourriez être en mesure ou non de réaliser les attaques suivantes.
Pour plus d'informations, consultez les informations de base :
Basic Jenkins InformationSi vous avez accédé à Jenkins, vous pouvez lister d'autres utilisateurs enregistrés à http://127.0.0.1:8080/asynchPeople/
Utilisez ce script pour extraire les sorties de la console de build et les variables d'environnement de build afin de trouver, espérons-le, des secrets en clair.
Si l'utilisateur compromis a suffisamment de privilèges pour créer/modifier un nouveau nœud Jenkins et que les crédentiels SSH sont déjà stockés pour accéder à d'autres nœuds, il pourrait voler ces crédentiels en créant/modifiant un nœud et en définissant un hôte qui enregistrera les crédentiels sans vérifier la clé de l'hôte :
Vous trouverez généralement les crédentiels ssh de Jenkins dans un fournisseur global (/credentials/
), vous pouvez donc également les extraire comme vous le feriez pour tout autre secret. Plus d'informations dans la section Extraction de secrets.
Obtenir un shell sur le serveur Jenkins donne à l'attaquant l'opportunité de divulguer tous les secrets et variables d'environnement et d'exploiter d'autres machines situées sur le même réseau ou même de rassembler des crédentiels cloud.
Par défaut, Jenkins s'exécute en tant que SYSTEM. Donc, le compromettre donnera à l'attaquant des privilèges SYSTEM.
Créer/Modifier un projet est un moyen d'obtenir RCE sur le serveur Jenkins :
Jenkins RCE Creating/Modifying ProjectVous pouvez également obtenir RCE en exécutant un script Groovy, qui pourrait être plus furtif que de créer un nouveau projet :
Jenkins RCE with Groovy ScriptVous pouvez également obtenir RCE en créant/modifiant un pipeline :
Jenkins RCE Creating/Modifying PipelinePour exploiter des pipelines, vous devez toujours avoir accès à Jenkins.
Les pipelines peuvent également être utilisés comme mécanisme de build dans des projets, dans ce cas, il peut être configuré un fichier à l'intérieur du dépôt qui contiendra la syntaxe du pipeline. Par défaut, /Jenkinsfile
est utilisé :
Il est également possible de stocker des fichiers de configuration de pipeline à d'autres endroits (dans d'autres dépôts par exemple) dans le but de séparer l'accès au dépôt et l'accès au pipeline.
Si un attaquant a un accès en écriture sur ce fichier, il pourra le modifier et déclencher potentiellement le pipeline sans même avoir accès à Jenkins. Il est possible que l'attaquant doive contourner certaines protections de branche (selon la plateforme et les privilèges de l'utilisateur, elles pourraient être contournées ou non).
Les déclencheurs les plus courants pour exécuter un pipeline personnalisé sont :
Demande de tirage vers la branche principale (ou potentiellement vers d'autres branches)
Pousser vers la branche principale (ou potentiellement vers d'autres branches)
Mettre à jour la branche principale et attendre qu'elle soit exécutée d'une manière ou d'une autre
Si vous êtes un utilisateur externe, vous ne devriez pas vous attendre à créer une PR vers la branche principale du dépôt d'un autre utilisateur/organisation et déclencher le pipeline... mais si c'est mal configuré, vous pourriez complètement compromettre des entreprises juste en exploitant cela.
Dans la section RCE précédente, une technique a déjà été indiquée pour obtenir RCE en modifiant un pipeline.
Il est possible de déclarer des variables d'environnement en texte clair pour l'ensemble du pipeline ou pour des étapes spécifiques. Ces variables d'environnement ne devraient pas contenir d'informations sensibles, mais un attaquant pourrait toujours vérifier toutes les configurations de pipeline/Jenkinsfiles :
Pour des informations sur la façon dont les secrets sont généralement traités par Jenkins, consultez les informations de base :
Basic Jenkins InformationLes identifiants peuvent être scopés à des fournisseurs globaux (/credentials/
) ou à des projets spécifiques (/job/<project-name>/configure
). Par conséquent, pour exfiltrer tous les identifiants, vous devez compromettre au moins tous les projets qui contiennent des secrets et exécuter des pipelines personnalisés/empoisonnés.
Il y a un autre problème, pour obtenir un secret à l'intérieur de l'env d'un pipeline, vous devez connaître le nom et le type du secret. Par exemple, si vous essayez de charger un secret usernamePassword
en tant que secret string
, vous obtiendrez cette erreur :
Voici comment charger certains types de secrets courants :
À la fin de cette page, vous pouvez trouver tous les types de credentials : https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
La meilleure façon de dump all the secrets at once est de compromettre la machine Jenkins (en exécutant un reverse shell dans le built-in node par exemple) et ensuite leaker les master keys et les encrypted secrets et les déchiffrer hors ligne. Plus d'informations sur la façon de faire cela dans la section Nodes & Agents et dans la section Post Exploitation.
D'après la documentation : La directive triggers
définit les manières automatisées dont le Pipeline doit être re-déclenché. Pour les Pipelines qui sont intégrés avec une source telle que GitHub ou BitBucket, triggers
peut ne pas être nécessaire car une intégration basée sur des webhooks sera probablement déjà présente. Les triggers actuellement disponibles sont cron
, pollSCM
et upstream
.
Exemple de Cron :
Vérifiez d'autres exemples dans la documentation.
Une instance Jenkins peut avoir différents agents fonctionnant sur différentes machines. Du point de vue d'un attaquant, l'accès à différentes machines signifie différentes potentielles informations d'identification cloud à voler ou différents accès réseau qui pourraient être abusés pour exploiter d'autres machines.
Pour plus d'informations, consultez les informations de base :
Basic Jenkins InformationVous pouvez énumérer les nœuds configurés dans /computer/
, vous trouverez généralement le Nœud intégré
(qui est le nœud exécutant Jenkins) et potentiellement plus :
Il est particulièrement intéressant de compromettre le nœud intégré car il contient des informations sensibles sur Jenkins.
Pour indiquer que vous souhaitez exécuter le pipeline dans le nœud Jenkins intégré, vous pouvez spécifier dans le pipeline la configuration suivante :
Pipeline dans un agent spécifique, avec un déclencheur cron, avec des variables d'environnement de pipeline et de stage, chargeant 2 variables dans une étape et envoyant un reverse shell :
Vous pouvez lister les secrets en accédant à /credentials/
si vous avez suffisamment de permissions. Notez que cela ne listera que les secrets à l'intérieur du fichier credentials.xml
, mais les fichiers de configuration de build peuvent également contenir plus de credentials.
Si vous pouvez voir la configuration de chaque projet, vous pouvez également y voir les noms des credentials (secrets) utilisés pour accéder au dépôt et d'autres credentials du projet.
Ces fichiers sont nécessaires pour décrypter les secrets Jenkins :
secrets/master.key
secrets/hudson.util.Secret
De tels secrets peuvent généralement être trouvés dans :
credentials.xml
jobs/.../build.xml
jobs/.../config.xml
Voici une regex pour les trouver :
Si vous avez extrait les mots de passe nécessaires pour déchiffrer les secrets, utilisez ce script pour déchiffrer ces secrets.
Accédez au fichier Jenkins config.xml dans /var/lib/jenkins/config.xml
ou C:\Program Files (x86)\Jenkins\
Recherchez le mot <useSecurity>true</useSecurity>
et changez le mot true
en false
.
sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
Redémarrez le serveur Jenkins : service jenkins restart
Maintenant, allez à nouveau sur le portail Jenkins et Jenkins ne demandera aucune information d'identification cette fois. Vous naviguez vers "Gérer Jenkins" pour définir à nouveau le mot de passe administrateur.
Activez à nouveau la sécurité en changeant les paramètres en <useSecurity>true</useSecurity>
et redémarrez à nouveau Jenkins.
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE) Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)