Builder

Publicado: 06 de Junio de 2025 Autor: Josรฉ Miguel Romero aKa x3m1Sec Dificultad: โญ Medium

๐Ÿ“ Descripciรณn

Builder es una mรกquina Linux de dificultad media que aloja un servidor Jenkins vulnerable. La mรกquina presenta una vulnerabilidad de lectura de archivos locales (LFI) en Jenkins a travรฉs del CVE-2024-23897, que permite acceder a archivos del sistema sin autenticaciรณn. Esta vulnerabilidad surge por el uso de la librerรญa args4j en el CLI de Jenkins, donde argumentos que comienzan con @ seguidos de una ruta de archivo son interpretados automรกticamente como contenido del archivo.

El proceso de explotaciรณn incluye el uso de esta vulnerabilidad para extraer archivos de configuraciรณn de Jenkins, especรญficamente archivos XML que contienen hashes de contraseรฑas de usuarios. Una vez obtenidas las credenciales mediante fuerza bruta, se aprovecha la consola de scripts de Jenkins (Groovy) para ejecutar cรณdigo arbitrario y obtener una shell reversa. Finalmente, se descubren credenciales SSH almacenadas en el sistema Jenkins para escalar privilegios al usuario root.

Categorรญas: ๐Ÿ” Credential Harvesting, ๐ŸŒ Web Exploitation, ๐Ÿณ Container Escape, ๐Ÿ”‘ SSH Key Extraction, ๐Ÿ’ป Jenkins Security

๐Ÿ”ญ Reconocimiento

Ping para verificaciรณn en base a TTL

๐Ÿ’ก Nota: El TTL cercano a 64 sugiere que probablemente sea una mรกquina Linux.

Escaneo de puertos

Enumeraciรณn de servicios


๐ŸŒ Enumeraciรณn Web

๐Ÿ—๏ธ Puerto 8080 HTTP (Jenkins 2.441)

Accedemos al puerto 8080 y descubrimos un servicio Jenkins. A priori no podemos enumerar gran cosa salvo un usuario llamado jennifer y la versiรณn de este servicio que es la 2.441 que es conocida por presentar una vulnerabilidad de tipo Local File Inclusion.

Y un panel de login en el que las credenciales por defecto no parecen funcionar.

CVE-2024-23897

ยฟQuรฉ es CVEโ€‘2024โ€‘23897?

  • Afecta a Jenkins Core (antes de la versiรณn 2.442) y Jenkins LTS (antes de la versiรณn 2.426.3). nvd.nist.govjenkins.io

  • Se origina por una caracterรญstica de la librerรญa args4j utilizada en el CLI: cuando un argumento comienza con @ seguido de un camino de archivo, Jenkins reemplaza automรกticamente esa sintaxis por el contenido del archivo โ€” incluso si no estรกs autenticado.

๐Ÿ”“ Cรณmo se explota

  1. El atacante descarga jenkins-cli.jar del servidor Jenkins.

  2. Usa @/ruta/al/archivo como argumento en un comando CLI, provocando que el contenido del archivo se revele. blog.certcube.comgithub.com

  3. Con los secretos obtenidos, podrรญan escalar a RCE usando los vectores mencionados arriba.

En este caso decido usar un script en python en lugar de usar jenkins-cli.jar aunque en caso de optar por la primera opciรณn el comando a utilizar serรญa algo como esto:

๐Ÿ Exploit en Python

Confirmamos la vulnerabilidad LFI leyendo el archivo /etc/passwd del sistema

Vemos que hay un usuario llamado jenkins en el sistema. Buscando informaciรณn sobre donde guarda Jenkins las credenciales de usuario, vemos que existe un archivo initialAdminPassword que deberรญa ubicarse en /var/jenkins_home/secrets/initialAdminPassword pero en este caso no obtenemos resultado:

Sin embargo, buscando y leyendo documentaciรณn sobre configuraciรณn de jenkins https://dev.to/pencillr/spawn-a-jenkins-from-code-gfa?source=post_page-----143ad7fde347---------------------------------------

encontramos que hay algunos otros ficheros como config.xml y users.xml que pueden ser de utilidad:

๐Ÿ“ /var/jenkins_home/users/users.xml

๐Ÿ“ /var/jenkins_home/config.xml

Lo interesante de esta informaciรณn estรก en la clave jennifer_12108429903186576833. Podemos usarla para continuar enumerando la informaciรณn especรญfica de este usuario:

๐Ÿ“ /var/jenkins_home/users/jennifer_12108429903186576833/config.xml

๐Ÿ”“ Cracking del Hash

Encontramos el hash de tipo bcrypt usuario jennifer:

Usamos hashcat y el diccionario rockyou para crackear este hash y obtener la contraseรฑa:

๐Ÿš€ Acceso Inicial

Volvemos ahora al panel de login Jenkins y nos autenticamos como jennifer:

Una vez dentro, como jennifer es admin ahora tenemos habilitadas todas las opciones del รกrbol de la izquierda, entre ellas estรก la funciรณn script console:

Esta consola permite a un usuario ejecutar Apache Groovy scripts, que son un lenguaje compatible con Java orientado a objetos. El lenguaje es similar a Python y Ruby. El cรณdigo fuente de Groovy se compila en Java Bytecode y puede ejecutarse en cualquier plataforma que tenga JRE instalado.

Usando esta consola de scripts, es posible ejecutar comandos arbitrarios, funcionando de manera similar a un shell web. Por ejemplo, podemos usar el siguiente fragmento para ejecutar el id comando.

Vemos que funcione y nos devuelve como el resultado del id del usuario jenkins.

Ahora veamos cรณmo podemos aprovechar esto para ganar acceso a la mรกquina. Podemos cambiar el payload anterior por:

Iniciamos un listener con netcat:

Ejecutar los comandos anteriores da como resultado una conexiรณn de shell inversa.

๐Ÿ› ๏ธ Mejora de la TTY

๐Ÿณ Anรกlisis del Entorno

Al tratar de enumerar usuarios en el directorio /home vemos que no hay nada. ยฟSerรก que estamos dentro de un contenedor?

Tal como sospechaba, estamos dentro de un contenedor tal como podemos confirmar viendo el fichero .dockerenv en la raรญz del sistema:

La flag user.txt la encontramos en el directorio /var/jenkins_home

๐Ÿ”‘ Escalada de Privilegios

Justo en el mismo directorio donde se ubica de la primera flag, vemos unos archivos con nombres que invitan a ver quรฉ son llamados secret.key, secret.key.not-so-secret y secrets:

Parece una clave ssh, pero no en el formato que se usa habitualmente sino que parece estar en hexadecimal. Quizรกs si logramos obtener una llave ssh podemos escapar del contenedor y lograr una escalada de privilegios.

Investigando sobre esto descubrimos un repositorio con utilidades de jenkins: https://github.com/tarvitz/jenkins-utils

Hay un script que podemos usar en la utilidad /script de nuestro jenkins para extraer los secrets de jenkins master siempre que seamos administradores. Como en este caso lo somos, basta con ejecutarlo y obtenemos la clave:

Copiamos la clave privada y la copiamos en un fichero en nuestro host de ataque y le damos permisos 600. Finalmente nos conectamos y ganamos acceso como root:

Last updated