Nmap

Like always, I’m going to scan the IP Address by using nmap but I’m going to scan the full port first. Then, I’m going to scan the only open ports.

# Nmap 7.94SVN scan initiated Fri Dec 29 21:37:10 2023 as: nmap -p22,80 -sCV -oN nmap/cozyhosting 10.10.11.230
Nmap scan report for 10.10.11.230
Host is up (0.048s latency).

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 Fri Dec 29 21:37:19 2023 -- 1 IP address (1 host up) scanned in 8.74 seconds

The Nmap scan results indicate that only two ports are open, SSH and HTTP. Based on the OpenSSH version, the target is most likely running Ubuntu 22.04 LTS, codename Jammy Jellyfish.

Additionally, Nmap discovered a hostname, cozyhosting.htb, which I added to my /etc/hosts file.

add hostname

Http: cozyhosting.htb

I navigated to port 80 in my browser and was greeted by a simple website that offers hosting solutions for various projects. The site also includes a login page, but after trying a few common credentials, none of them worked.

cozyhosting.htb home page

Next, I performed directory busting using Gobuster. It didn’t reveal anything particularly interesting except for the /admin directory, which returned a status code 401. I attempted to bypass it, but without success.

While browsing the website, I encountered an error page displaying a Whitelabel Error Page. After some quick research, I discovered that this error is associated with Spring Boot.

Spring Boot error

Http: /actuator/sessions

Fortunately, the SecLists repository includes a wordlist dedicated to Spring Boot. I ran Gobuster again with this wordlist, and it successfully discovered the /actuator/sessions endpoint.

gobuster using spring-boot.txt

When I navigated to this endpoint in my browser, I found session cookies belonging to a user named kanderson.

kanderson session cookies

Http: admin dashboard

Next, I replaced the current cookie with the one I discovered, and upon refreshing the page, I successfully logged into the dashboard as kanderson with admin privileges.

cozy cloud dashboard

The dashboard also features an input form that allows an admin to connect to a machine via SSH by supplying a hostname and username. I tried using kanderson’s username along with some common usernames for the SSH connection, but nothing happened.

SSH on admin dashboard

After sending the request to the Repeater in Burp Suite and experimenting with special characters like ;, I received an error message resembling an SSH command help menu. This indicates that the SSH command is being executed with the supplied user input.

SSH command error

Shell: app

I then attempted to escape the SSH command to achieve command injection. Although the system initially rejected spaces, I managed to craft a command that executed a reverse shell while bypassing the spacing filter using ${IFS}.

Once executed successfully, I obtained a shell as the app user. I then upgraded my reverse shell to a full TTY using Python.

shell as app

In the /app directory, which was my current working directory, I discovered the JAR file cloudhosting-0.0.1.jar. I exfiltrated this file using the nc command for further analysis.

exfiltrate cloudhosting-0.0.1.jar

Since a JAR file is essentially a ZIP archive, I used a simple unzip command to extract its contents. My first step was to search for any strings containing the word “password” using grep. This search revealed a plaintext password in the file BOOT-INF/classes/application.properties.

found plaintext password

PostgreSQL: credentials

Reading through the application.properties file revealed additional interesting information, including PostgreSQL credentials for a database listening on localhost at port 5432.

postgresql credentials

I connected to the PostgreSQL database using the psql command-line utility with the following command psql -h localhost -U postgres -d cozyhosting.

After some basic enumeration (using commands similar to those described in this blog post), I found user hashes belonging to admin and kanderson.

hash inside postgresql

Hashcat

I saved the discovered hash into a file named hashes.txt on my machine and used Hashcat with the -m 3200 flag (indicating a bcrypt hash) to crack it. Fortunately, Hashcat was able to crack the hash and reveal the plaintext password.

cracking hash using hashcat

The cracked password appears to belong to an admin user. I then listed all users on the machine (using the foothold I had achieved via command injection) and confirmed that there were several users.

listing all users

SSH: josh

Next, I logged in using the credentials obtained from Hashcat for the user josh. The login was successful. With valid credentials in hand, I checked the sudo permissions using sudo -l and discovered that josh can execute the SSH command with sudo privileges.

ssh as josh

Shell: root

I then consulted GTFOBins, which is a collection of Unix binaries that can be exploited for privilege escalation. Searching for how to abuse SSH for root access, I executed the following command sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x. This command successfully escalated my privileges, granting me a root shell.

becoming root