This is a write up on how I solved Zetta from Hack the Box, which is an online platform where you can play various CTFs and practice your penetration testing skills.

As always, I try to explain how I understood the concepts here from the machine because I want to really understand how things work. So please, if I misunderstood a concept, please let me know.

TL;DR

I liked the Zetta machine because every step required was new for me. It took me a long time to root this box. Its difficulty is rated as hard.

It starts with initiating a connection from the FTP service to leak an IPv6 address. Scanning the IPv6 address reveals the service rsync, which allows me to upload/download files, leading to more enumeration. I then create a bash script to guess the user’s password. For root, I exploit a PostgreSQL injection from its logging using the logger command, and look back to the user’s to-do files to identify the password scheme for root. I definitely learned a lot from this difficult box.

Recon

I first start by running an nmap scan:

# nmap -p- -oA nmap/allports 10.10.10.156 PORT STATE SERVICE

21/tcp open ftp

22/tcp open ssh

80/tcp open http

Seeing that the services ftp, ssh, and http are open for TCP, I run another nmap this time with version scanning(-sV) and default nmap scripts (-sC):

nmap -sV -sC -p21,22,80 -oA nmap/initial 10.10.10.156 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

Seeing the services running and their versions, I first try to connect to FTP to check for anonymous login, but this is the banner:

It tells us that its a private system and no anonymous login allowed. Note also that it mentions IPv6 connections are also welcome on this server. Since port 80/http is open with its title as Ze::a Share(another clue that we are going to deal with something about IPv6 here, as “::” is used in place of many zeros in IPv6), I check it out.

HTTP

Checking the page, there are a few things to note about it. It mentions that they offer NAS(Network Access Storage) service.

It also mentions stuff that they do. The only thing that makes sense is Native FTP. Which mentions FTP with FXP and RFC2428.

It also mentions “Dual-Stack”, which I remember is a term introduced to me in university when a device can be reached using both IPv4 and IPv6 addresses.

The team are characters from the TV series “The IT Crowd”. I can get some possible users here.

The page also mentions credentials that I can use on the FTP server.

They also have a Get In Touch section, but it isn’t functional.

Viewing the source of the page, there is a script that generates a random 32 character string. This is for the username and password fields. It indicates that the login for the FTP can be anything as long as its 32 characters.

RFC 2428

They mentioned RFC 2428. RFC stands for Request For Comments. Quoting from Wikipedia:

An RFC is authored by engineers and computer scientists in the form of a memorandum describing methods, behaviors, research, or innovations applicable to the working of the Internet and Internet-connected systems. It is submitted either for peer review or to convey new concepts, information, or occasionally engineering humor.

RFC2428 mentions the following:

With the deployment of version 6 of the Internet Protocol, network addresses will no longer be 32-bits. This paper specifies extensions to FTP that will allow the protocol to work over IPv4 and IPv6. This document provides a specification for a way that FTP can communicate data connection endpoint information for network protocols other than IPv4. In this specification, the FTP commands PORT and PASV are replaced with EPRT and EPSV, respectively. The EPRT command allows for the specification of an extended address

for the data connection. The extended address MUST consist of the

network protocol as well as the network and transport addresses. The

format of EPRT is:

EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d>

A quick review of FTP:

FTP stands for File Transfer Protocol. It allows you to transfer files between 2 hosts. It uses 2 ports, one for sending commands(command port) and for transferring data(data port). The data port varies depending on what mode is used.

Active Mode:

The client(in this case, my machine) connects using a random port to port 21 of the FTP server (Zetta box).

The client tells the FTP server(Zetta box) “connect your port 20 to the port I will define and send data to that port”. This can be done using the PORT command for IPv4, and EPRT command for IPv6

The client sends command to port 21 of the FTP server, and the server sends data from port 20 to the defined port of the client

The data connection is initiated by the server

Passive mode:

The client connects using a random port to port 21 of the FTP server.

The client asks the FTP server “what port are you going to open for our data connection? Please tell me and I will connect to it”. This is done thru the PASV command.

The client acknowledges the port opened by the data connection and connects to that port for data transfer.

The data connection is initiated by the client

Knowing all that, it all leads to a clue that I can leak the IPv6 address of the machine, and it may reveal other services that are running.

To verify that the FTP login accepts any 32 character username and password, I verified it using 32 A’s, and it worked.

I then tried to follow how to use PORT in IPv6 based on the RFC. I also set up my listener and gave it my IPv6 address and run a LIST command(like a dir or ls). I get a connection from the box, revealing its IPv6 address.

Enumerating thru IPv6 address

I try to ping the IPv6 address, and I get Echo Replies.

I then try to run an nmap scan against the host using its IPv6 address:

# nmap -6 -sV -sC dead:beef::250:56ff:feb9:5dfd

The results reveal the same ports and the same ssh-hostkey(which should unique for each box) as the previous scan.

I also tried to run a TCP all ports scan, and it reveals port 8730 is open.

# nmap -6 -p- dead:beef::250:56ff:feb9:5dfd PORT STATE SERVICE

21/tcp open ftp

22/tcp open ssh

80/tcp open http

8730/tcp open unknown

I then ran a version scan and default scripts scan to learn more about the service. The scan reveal that the service running on port 8730 is rsync.

# nmap -6 -p 8730 -sV -sC dead:beef::250:56ff:feb9:5dfd PORT STATE SERVICE VERSION

8730/tcp open rsync (protocol version 31)

RSYNC

According to the man page, rsync is a fast, versatile, remote (and local) file-copying tool. One way that I can enumerate the modules available on rsync is through Metasploit. By using the auxiliary/scanner/rsync/modules_list, I can see that 9 modules are found.

I can also connect to the rsync daemon using the following syntax:

rsyncrsync://IPADDR:RsyncPort

I try to connect to the rsync service. Note that when dealing with IPv6 addresses, you should place them inside brackets:

rsync rsync://[dead:beef::250:56ff:feb9:5dfd]:8730

I am prompted by the rsync server banner and the modules available, while mentioning that it is illegal to connect to the server. Knowing that this is a CTF, I can neglect the warning.

Note that the modules listed are usually found under the Linux directory “/”. I try to list one of the modules, but get access denied.

One of the missing directories under “/” is /etc. I try to list files under /etc. It seems that I have access.

I try to check if I have access to files that are usually configured to be readable by anyone. One of those is the /etc/passwd file. It has minimal permissions because many processes in the system needs read access to identify permissions of certain users. Having said that, I tried to download /etc/passwd, and it worked. I can see the users, and one of them is roy. I download a copy to my local machine:

rsync -r rsync://[dead:beef::250:56ff:feb9:5dfd]:8730/etc/passwd .

Looking more into rsync’s documentation, I can check if the configuration file is at /etc/rsyncd.conf

I grab a copy and read it locally:

Rsync by default listens on port 873. I can see in the configuration file that it was modified to listen on port 8730. That’s why nmap wasn’t able to initially identify what service is running. Checking the config for the modules, /etc is configured to exclude .git and to not be listed. But this config doesn’t prevent anyone from guessing the name of the module.

In the lower part of the config file, there is a module called home_roy which is mapped to the /home/roy directory.

Knowing that only roy can access it, I need to be able to get the password of roy. I tried to rsync to the home_roy module, and it asks me for a password.

I can guess roy’s password, but there are prompts, resulting to much more time doing it manually. I looked into other ways I can send the password, and found out I can do this by setting the environment variable. I resorted to brute force it using a bash script.

Running the script:

The script stopped at the password “computer”.

I try to rsync to home_roy, and I can now see the files under /home/roy. I will then try to rsync a .ssh directory, containing my public key under the file authorized_keys, and try to ssh into the box.

I create first a key pair using ssh-keygen:

I then renamed my public key to authorized_keys, dropped the whole ssh folder using rsync, and changed my private key’s permission.

I login using ssh, and can now read user.txt.

Roy → Postgres

Note that there is a .tudu.xml file:

I grab a copy and opened it using my browser. It is mentioned that Roy is not yet done reworking rsyncd.conf. This is the reason why /etc is accessible.

There is also a section indicating that he’s using rsyslog and that the logs are being pushed to DB.

Far below, it mentions that Roy needs to change the shared password scheme. Currently its <secrer>@userid.

Roy also mentioned in the /rsyncd.conf to exclude .git in the listing of /etc in rsync:

Knowing that there may be git folders, which are very interesting, I tried to look for them using the find command:

find / -name ".git" -type d 2>/dev/null

3 git folders came up. All these services are mentioned in the tudu.xml. Checking files under rsyslog.d, there is a config file that I can’t read.

One of my first checks when dealing with git repos is checking the commits:

git log -p

The commit shows the changes done to pgsql.conf. Indicating creds(they don’t work anywhere else) and the template of how the logs will be pushed to Postgre. All clues lead now to Postgre injection using the logs. I check the contents of postgreql main log and tried generating some logs using the logger command:

watch -n 1 cat postgresql-11-main.log

I know try to play with the logging: