Jenkins Security
Informations de base
Jenkins est un outil qui offre une méthode simple pour établir un environnement d'intégration continue ou de déploiement continu (CI/CD) pour presque toute combinaison de langages de programmation et de référentiels 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 l'on peut facilement construire manuellement.
pageBasic Jenkins InformationÉnumération non authentifiée
Pour rechercher des pages Jenkins intéressantes sans authentification comme (/people ou /asynchPeople, qui répertorie 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 les noms d'utilisateur.
Vous pouvez 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 vous connecter à Jenkins:
pageBasic Jenkins InformationEnregistrement
Vous pourrez trouver des instances de Jenkins qui vous permettent de créer un compte et de vous connecter à l'intérieur. Aussi simple que cela.
Connexion SSO
Également, si la fonctionnalité/plugins SSO étaient présents, vous devriez essayer de vous connecter à l'application en utilisant un compte de test (par exemple, un compte Github/Bitbucket de test). Astuce provenant de ici.
Bruteforce
Jenkins manque de politique de mot de passe et de mitigation de la force brute pour les noms d'utilisateur. Il est essentiel de forcer la recherche des utilisateurs car des mots de passe faibles ou des noms d'utilisateur comme mots de passe peuvent être utilisés, voire des noms d'utilisateur inversés comme mots de passe.
Password spraying
Utilisez ce script python ou ce script powershell.
Contournement du filtrage par adresse IP
De nombreuses organisations combinent des systèmes de gestion de contrôle de source (SCM) basés sur le cloud tels que GitHub ou GitLab avec une solution CI auto-hébergée interne comme Jenkins ou TeamCity. Cette configuration permet aux systèmes CI de recevoir des événements de webhook des fournisseurs de contrôle de source basés sur le cloud, principalement pour déclencher des tâches de pipeline.
Pour ce faire, les organisations autorisent en liste blanche les plages d'adresses IP des plateformes SCM, leur permettant d'accéder au système CI interne via des webhooks. Cependant, il est important de noter que n'importe qui 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 supposons que vous disposez d'un compte valide pour accéder à Jenkins.
En fonction du mécanisme d'Autorisation configuré dans Jenkins et des autorisations de l'utilisateur compromis, vous pourriez être en mesure ou non d'effectuer les attaques suivantes.
Pour plus d'informations, consultez les informations de base :
pageBasic Jenkins InformationListe des utilisateurs
Si vous avez accédé à Jenkins, vous pouvez lister les autres utilisateurs enregistrés sur http://127.0.0.1:8080/asynchPeople/
Extraction des builds pour trouver des secrets en clair
Utilisez ce script pour extraire les sorties de console de build et les variables d'environnement de build 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 des 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é d'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.
RCE dans Jenkins
Obtenir un shell dans 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 dans le même réseau ou même de collecter des crédentiels cloud.
Par défaut, Jenkins s'exécutera en tant que SYSTEM. Ainsi, le compromettre donnera à l'attaquant des privilèges SYSTEM.
RCE Création/Modification d'un projet
Créer/Modifier un projet est une façon d'obtenir une RCE sur le serveur Jenkins :
pageJenkins RCE Creating/Modifying ProjectRCE Exécuter un script Groovy
Vous pouvez également obtenir une RCE en exécutant un script Groovy, ce qui pourrait être plus discret que de créer un nouveau projet :
pageJenkins RCE with Groovy ScriptRCE Création/Modification de Pipeline
Vous pouvez également obtenir une RCE en créant/modifiant un pipeline :
pageJenkins RCE Creating/Modifying PipelineExploitation de Pipeline
Pour exploiter les pipelines, vous devez toujours avoir accès à Jenkins.
Construire des Pipelines
Les pipelines peuvent également être utilisés comme mécanisme de construction dans les projets, dans ce cas, un fichier à l'intérieur du dépôt peut être configuré pour contenir la syntaxe du pipeline. Par défaut, /Jenkinsfile
est utilisé :
Il est également possible de stocker des fichiers de configuration de pipeline ailleurs (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 accès en écriture à 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 :
Pull request 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 s'il est mal configuré, vous pourriez compromettre complètement des entreprises en exploitant cela.
RCE de Pipeline
Dans la section RCE précédente, une technique pour obtenir une RCE en modifiant un pipeline a déjà été indiquée.
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 l'ensemble du pipeline configurations/Jenkinsfiles :
Extraction de secrets
Pour des informations sur la manière dont les secrets sont généralement traités par Jenkins, consultez les informations de base :
pageBasic Jenkins InformationLes informations d'identification peuvent être définies pour les fournisseurs globaux (/credentials/
) ou pour des projets spécifiques (/job/<nom-du-projet>/configure
). Par conséquent, pour exfiltrer tous les secrets, vous devez compromettre au moins tous les projets contenant des secrets et exécuter des pipelines personnalisés/empoisonnés.
Il y a un autre problème, pour obtenir un secret dans l'environnement 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 de type string
, vous obtiendrez cette erreur:
Voici la manière de charger certains types de secrets courants :
À la fin de cette page, vous pouvez trouver tous les types d'informations d'identification: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
La meilleure façon de dumper toutes les secrets en une fois est de compromettre la machine Jenkins (en exécutant par exemple un shell inversé dans le nœud intégré) puis de fuir les clés maîtresses et les secrets chiffrés et de les décrypter hors ligne. Pour en savoir plus sur la façon de faire cela, consultez la section Nodes & Agents et la section Post Exploitation.
Déclencheurs
D'après la documentation: La directive triggers
définit les méthodes automatisées par lesquelles le Pipeline doit être relancé. Pour les Pipelines intégrés à une source telle que GitHub ou BitBucket, les triggers
peuvent ne pas être nécessaires car une intégration basée sur les webhooks sera probablement déjà présente. Les déclencheurs actuellement disponibles sont cron
, pollSCM
et upstream
.
Exemple de Cron:
Consultez d'autres exemples dans la documentation.
Noeuds & Agents
Une instance de Jenkins peut avoir différents agents s'exécutant sur différentes machines. Du point de vue d'un attaquant, l'accès à différentes machines signifie différentes informations d'identification cloud potentielles à voler ou différents accès réseau qui pourraient être exploités pour attaquer d'autres machines.
Pour plus d'informations, consultez les informations de base :
pageBasic Jenkins InformationVous pouvez énumérer les noeuds configurés dans /computer/
, vous trouverez généralement le **Noeud Intégré
** (qui est le noeud exécutant Jenkins) et potentiellement d'autres :
Il est particulièrement intéressant de compromettre le noeud intégré car il contient des informations sensibles sur Jenkins.
Pour indiquer que vous souhaitez exécuter le pipeline dans le noeud 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, chargement de 2 variables dans une étape et envoi d'un shell inversé:
Post Exploitation
Metasploit
Secrets de 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 davantage 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.
En Groovy
pageJenkins Dumping Secrets from GroovyDepuis le disque
Ces fichiers sont nécessaires pour décrypter les secrets de 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échiffrer les secrets de 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échiffrer les secrets Jenkins à partir de Groovy
Créer un nouvel utilisateur administrateur
Accédez au fichier config.xml de Jenkins 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
Retournez sur le portail Jenkins et Jenkins ne demandera pas de mots de passe cette fois. Accédez à "Gérer Jenkins" pour définir à nouveau le mot de passe administrateur.
Activez à nouveau la sécurité en modifiant les paramètres en
<useSecurity>true</useSecurity>
et redémarrez Jenkins à nouveau.
Références
Dernière mise à jour