Intermediate·250 points·0 solves
VaultDocs — File Upload Bypass
Learn file upload bypass: when "is this an allowed file type" is decided from attacker-controlled signals (the Content-Type header, or a substring match on the filename) instead of the file's actual content, an attacker can disguise one file type as another and reach server-side processing meant only for safe formats.
VaultDocs accepts a file if its multipart Content-Type header is image/jpeg, image/png, image/gif or application/pdf, AND its filename contains one of .jpg/.jpeg/.png/.gif/.pdf anywhere — not necessarily at the end. Both checks are attacker-controlled: you set the Content-Type header yourself when uploading, and a name like profile.jpg.phtml contains '.jpg' while actually ending in .phtml. VaultDocs treats any stored file ending in .phtml as a "document to process": it runs the file's contents through a small template step that substitutes {{ name }} placeholders from a fixed set of values — one of which is the flag. So a disguised upload containing {{flag}} gets the flag substituted in when you view it. The fix is to validate the file's real content (magic bytes / a proper image-decode check, not the declared Content-Type), to match the extension with endswith against an allow-list, and to store uploads outside the web root under a randomised name so a stored file can never be requested by a predictable path.
Your tasks
1
Upload normally
Open the lab and upload a real image. VaultDocs stores it and lets you view it — nothing interesting happens yet.
2
Find the validation logic's blind spot
VaultDocs checks the Content-Type you declare and whether an allowed extension appears anywhere in the filename. Both of those are things YOU control as the uploader.
3
Craft a disguised upload
Name a file profile.jpg.phtml (so '.jpg' is in the name) and set its Content-Type to image/jpeg. VaultDocs accepts it as a valid image.
4
Trigger processing
Anything stored with a .phtml name is "processed" when viewed. Put {{flag}} in the file's contents before uploading it.
5
Capture the flag
View the uploaded .phtml file. The flag is substituted into the processed output.
Submit the flag
Start the lab, capture the flag from the running machine, and submit it here.