Jenkins Security
Basic Information
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 InformationUnauthenticated Enumeration
Afin 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.
Vulnérabilités Connues
Connexion
Dans les informations de base, vous pouvez vérifier toutes les façons de se connecter à Jenkins :
Basic Jenkins InformationInscription
Vous pourrez trouver des instances de Jenkins qui vous permettent de créer un compte et de vous y connecter. Aussi simple que cela.
Connexion SSO
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 compte Github/Bitbucket test). Astuce de ici.
Bruteforce
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.
Password spraying
Utilisez ce script python ou ce script powershell.
Contournement de la liste blanche IP
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 contrôle de source SaaS, principalement pour déclencher des travaux de pipeline.
Pour ce faire, les organisations mettent sur 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.
Abus internes de Jenkins
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 InformationListe des utilisateurs
Si vous avez accédé à Jenkins, vous pouvez lister d'autres utilisateurs enregistrés à http://127.0.0.1:8080/asynchPeople/
Dumping des builds pour trouver des secrets en clair
Utilisez ce script pour extraire les sorties de la console de construction et les variables d'environnement de construction afin de trouver des secrets en clair.
Vol de crédentiels SSH
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 Dumping secrets.
RCE dans Jenkins
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.
RCE Création/Modification d'un projet
Créer/Modifier un projet est un moyen d'obtenir RCE sur le serveur Jenkins :
Jenkins RCE Creating/Modifying ProjectRCE Exécution de script Groovy
Vous 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 ScriptRCE Création/Modification de Pipeline
Vous pouvez également obtenir RCE en créant/modifiant un pipeline :
Jenkins RCE Creating/Modifying PipelineExploitation de Pipeline
Pour exploiter les pipelines, vous devez toujours avoir accès à Jenkins.
Pipelines de Build
Les pipelines peuvent également être utilisés comme mécanisme de build dans les 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.
RCE de Pipeline
Dans la section RCE précédente, une technique a déjà été indiquée pour obtenir RCE en modifiant un pipeline.
Vérification des variables d'environnement
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 :
Dumping secrets
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 nœud intégré, 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.
Triggers
D'après la documentation : La directive triggers
définit les manières automatisées dont le Pipeline doit être relancé. 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.
Nœuds & Agents
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 de 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 :
Exemple complet
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 :
Lecture de fichiers arbitraires à RCE
Jenkins Arbitrary File Read to RCE via "Remember Me"RCE
Jenkins RCE with Groovy ScriptJenkins RCE Creating/Modifying ProjectJenkins RCE Creating/Modifying PipelinePost exploitation
Metasploit
Secrets Jenkins
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.
Depuis Groovy
Jenkins Dumping Secrets from GroovyDepuis le disque
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 :
Décrypter les secrets Jenkins hors ligne
Si vous avez extrait les mots de passe nécessaires pour déchiffrer les secrets, utilisez ce script pour déchiffrer ces secrets.
Décrypter les secrets Jenkins depuis Groovy
Créer un nouvel utilisateur administrateur
Accédez au fichier Jenkins config.xml dans
/var/lib/jenkins/config.xml
ouC:\Program Files (x86)\Jenkins\
Recherchez le mot
<useSecurity>true</useSecurity>
et changez le mottrue
enfalse
.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.
Références
Last updated