OSCP Prep #17 HTB Write-Up Pilgrimage

1. Target Overview
Machine Name: Pilgrimage
Platform: Hack The Box
Operating System: Linux
Target IP: 10.129.9.115
Objective: Gain initial access to the target system and escalate privileges to obtain full system compromise.
Pilgrimage was one of the more instructive machines I’ve worked through so far. It combined a clean initial foothold with a privilege escalation path that really forced me to understand what the system was doing behind the scenes.
Tools Used
Nmap
RustScan
ffuf
git-dumper
pngcrush
sqlite3
searchsploit
binwalk
netcat
2. Enumeration
Initial Reconnaissance
As always, I started with a port scan using RustScan to quickly identify open ports and pass them into Nmap for deeper analysis.
rustscan -a 10.129.9.115 -b 7000 -- -sC -sV -T4
The results showed a very narrow attack surface:
Port 22 (SSH)
Port 80 (HTTP)
Since SSH is rarely useful without credentials, I focused on the web server.
During the scan, I noticed a redirect to pilgrimage.htb, so I added it to my /etc/hosts file.
Web Enumeration
I began with virtual host fuzzing to see if there were additional domains:
ffuf -u http://10.129.9.115 -H "Host: FUZZ.pilgrimage.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
No additional domains were discovered, so I moved on to directory fuzzing:
ffuf -u http://pilgrimage.htb/FUZZ -w /usr/share/wordlists/elite.txt -fc 403
This revealed a key finding:
.git/
An exposed .git directory is always a strong signal that source code may be recoverable, which can completely change how you approach the box.
Application Analysis
Browsing the site, I found an image compression application. Since user-uploaded files were being processed on the server, this immediately stood out as a potential attack surface.
My first instinct was command injection. The logic is straightforward: if user input is passed into a system binary without proper sanitization, it can lead to remote command execution.
However, I ran into a few constraints:
I could not control the filename being passed to the backend
File uploads were filtered (PHP files were blocked)
Changing extensions or embedding PHP code did not bypass the filter
At this point, it was clear that direct RCE through file upload was not the intended path, so I shifted focus.
3. Exploitation
Source Code Disclosure via .git
The exposed .git directory allowed me to reconstruct the full repository:
git-dumper http://pilgrimage.htb/.git src
This removed guesswork entirely. Instead of probing blindly, I could now see exactly how the application worked.
While reviewing the source, I found that uploaded images were processed using a binary called magick, part of ImageMagick.
LFI via ImageMagick (What’s Actually Happening)
ImageMagick processes images by parsing both the image data and any embedded metadata. One feature it supports is embedded profiles inside image files.
The vulnerability here comes from how those profiles are interpreted.
Using pngcrush, I created a malicious PNG:
pngcrush -text a "profile" "/etc/passwd" input.png output.png
Here’s what’s happening behind the scenes:
The PNG includes a text chunk labeled
profileInstead of treating this as harmless metadata, ImageMagick treats it as a file reference
It attempts to open and read the file from disk
The contents of that file are embedded into the processed output image
So when the application processes the image:
/etc/passwdis read on the serverIts contents are injected into the output
That output is returned to me
This effectively gives me a file read primitive through the backend.
The key point here is that this is not a traditional LFI through a URL parameter—this is LFI through abusing how a backend library parses user-controlled input.
Why RFI Was Not an Option
At this point, a common instinct is to try Remote File Inclusion to get code execution.
That doesn’t apply here.
This vulnerability:
Only reads local files
Does not execute what it reads
Does not support remote paths
Credential Extraction via LFI
Instead of chasing RCE, I shifted focus to what LFI is best at: reading sensitive data.
From reviewing the source code, I already knew the application used a SQLite database. That immediately became my target.
Using the same technique, I extracted the database file, rebuilt it locally, and dumped its contents:
xxd -r -p pil.db.hex > pil.db
sqlite3 pil.db
.dump
This revealed credentials for a valid user:
INSERT INTO users VALUES('emily','abigchonkyboi123');
Initial Access
With SSH open, I used the recovered credentials to log in as emily and gained a shell on the system.
4. Privilege Escalation
Binwalk Vulnerability
Inside Emily’s home directory, I found a reference to binwalk. Checking the version showed it was vulnerable to command execution.
Binwalk analyzes files by extracting embedded data and processing it. The issue is that it does not safely handle certain extracted content, which allows crafted files to trigger command execution.
However, running the exploit directly would only give me a shell as emily, so I needed to find where binwalk was being used with higher privileges.
Root Script Behavior
Using:
ps auxww
I discovered a root-owned process monitoring a directory:
/usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/
The system watches for new files
When a file is created, a script runs
That script processes the file using binwalk
The script runs as root
This creates a dangerous condition:
A privileged process is automatically handling user-controlled input.
Exploitation
Create a malicious file targeting the binwalk vulnerability
Place it in the monitored directory
Wait for the root script to process it
When the script triggered, it executed binwalk as root against my payload, resulting in a reverse shell.
5. Lessons Learned
1. LFI Is About Data First, Not Execution
One of the biggest takeaways from this box is that LFI is not always about getting code execution. In many cases, its real value comes from reading sensitive files such as databases, configuration files, or credentials. In this case, focusing on data extraction instead of forcing RCE led directly to a working foothold.
2. Source Code Changes Everything
Having access to the application’s source code through the exposed .git directory removed guesswork entirely. Instead of blindly testing inputs, I was able to understand how the application worked, identify backend components, and target specific files with purpose.
3. File Processing Is a High-Risk Attack Surface
Applications that process user-uploaded files introduce complex parsing behavior. Tools like ImageMagick are powerful but can interpret metadata in unexpected ways, which creates opportunities for vulnerabilities like this one. Any time files are being processed server-side, it should immediately raise attention.
4. Automation Combined with Privilege Is Dangerous
The privilege escalation in this box was not just about a vulnerable binary—it was about how that binary was being used. A root process was automatically executing binwalk on user-controlled input, which created a reliable path to escalation. Automation without proper safeguards is a serious risk.
5. Running Processes Often Reveal the Path Forward
The ps auxww output directly exposed the privilege escalation vector. Without checking running processes, it would have been much harder to identify how binwalk was being used. This reinforces how critical process enumeration is during privesc.
6. Defensive Insight
1. Do Not Expose .git Directories
Exposing a .git directory in production allows attackers to reconstruct the entire codebase, including sensitive logic and configuration details. This should always be blocked at the web server level.
2. Secure File Processing Pipelines
Any application that processes uploaded files must strictly validate and sanitize input. User-controlled data should never be passed directly into system-level tools without proper handling or isolation.
3. Patch Third-Party Dependencies
Both ImageMagick and binwalk had known vulnerabilities that were exploited in this box. Keeping dependencies updated is one of the simplest and most effective ways to prevent these types of attacks.
4. Restrict Access to Sensitive Files
Database files and other sensitive resources should not be readable by components that interact with user input. Proper file permission controls can significantly limit the impact of vulnerabilities like LFI.
5. Avoid Root-Level Automation on Untrusted Input
Automated processes running as root should never directly process user-controlled data. If automation is required, it should be isolated, validated, and run with the least privileges necessary.
7. Useful Commands
Virtual Host Fuzzing (Discover Subdomains)
ffuf -u http://10.129.9.115 -H "Host: FUZZ.pilgrimage.htb" -w
/usr/share/seclists/Discovery/DNS/subdomains-t
Dump Exposed .git Repository
git-dumper http://pilgrimage.htb/.git src
Craft Malicious PNG for LFI (ImageMagick Abuse)
pngcrush -text a "profile" "/etc/passwd" input.png output.png
Reconstruct Extracted Database File
xxd -r -p pil.db.hex > pil.db
Read SQLite Database Contents
sqlite3 pil.db
.dump
Enumerate Running Processes
ps auxww






