Upload Vulnerabilities
π Resources π
Attack Methodology
To tackle file upload challenges, begin by examining the website to identify its technology and potential attack vectors (e.g. upload pages), using tools like Wappalyzer or Burpsuite to gather information from headers and server responses (e.g. server, x-powered-by).
Locate an upload page and review its client-side scripts for filters.
Perform a test upload with an innocent file to understand how the website processes and stores uploads (upload dir, embedding, naming scheme), using tools like Gobuster to find uploaded file locations (-x switch in Gobuster).
Once the upload behavior is understood, attempt to bypass client-side filters with a malicious file and analyze any server-side rejection for clues.
Common server-side filters include extension whitelists/blacklists, magic number checks, MIME type validation, or file size restrictions, which can be identified through systematic testing, such as altering file attributes (e.g. invalid file extension, magic number, file size) or intercepting upload requests (e.g. change MIME type with BurpSuite). Use this information to refine your approach and improve the likelihood of a successful exploit.
Remote Code Execution (RCE)
Client-Side filtering bypass
Check source code of http://java.uploadvulns.thm/
client-side-filter.js
Waits for the window to load.
Sets up an event listener on a file input.
Validates that the selected file is a PNG image.
Displays the file name if valid or clears and hides input if invalid.
Manages UI feedback using additional functions (
error,success).
Find the images upload directory:
Try to upload a
.pngfile and check correct uploading at http://java.uploadvulns.thm/images(2nd option: prevent
client-side-filter.jsfile from being loaded by intercepting the response with Burp)
Change
php-reverse-shell.phpextension and catch the upload request with BurpSuiteas the MIME type (based on the file extension) automatically checks out, the Client-Side filter lets the payload through without complaining
In the intercepted request, change the to
filenameand theContent-Typeto the following values and then forward the request

Set up a
nclistener and navigate to http://java.uploadvulns.thm/images/shell.php to receive the reverse shell
Server-Side filtering bypass - extensions
π "The key to bypassing any kind of server side filter is to enumerate and see what is allowed, as well as what is blocked; then try to craft a payload which can pass the criteria the filter is looking for."
Find the assets folder
http://annex.uploadvulns.thm/privacy/ - this is where the files are uploaded with randomized naming scheme
Try to upload
shell.php- errorsTry to upload
shell-png.php- errorsTry to upload
shell.php5- works, file uploaded successfullySet up a
nclistener and navigate to http://annex.uploadvulns.thm/privacy/Access the randomized naming
*-shell.php5file to receive the reverse shell
Server-Side filtering bypass - magic numbers
π Magic numbers, the initial hex digits in a file, can validate file uploads by matching against a whitelist or blacklist, though their reliability varies by webserver type.
Try to upload
shell.php- errors "GIFs only please!"Duplicate
shell.phptomagic.phpfile. Edit it with a hex editor and add the GIF file signature (ASCII isGIF87a- check Wikipedia )Upload the new
magic.phpfile with GIF Hex signature - "File successfully uploaded"Set up a
nclistener and navigate to http://magic.uploadvulns.thm/graphics/magic.phpAccess the randomized naming
*-shell.php5file to receive the reverse shell
Final challenge - Jewel
Open http://jewel.uploadvulns.thm/
Using Wappalyzer
Node.js server (Header -
X-Powered-By: Express)Create a
jewel.jspayload file with this code (source - https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-reverse-cheatsheet/#nodejs)
Check source code and the available
.jsfiles
http://jewel.uploadvulns.thm/assets/js/upload.js
File Validation:
File Size Check: Ensures the file size is less than 50 KB.
Magic Number Check: Validates the fileβs magic number to ensure it's a JPEG image (
ΓΏΓΓΏ).File Extension Check: Confirms the file extension is
.jpgor.jpeg.
Trying to upload a valid jpeg file this is the BurpSuite POST request
The home webpage load some background images with this name structure
XXX.jpgfrom the/contentdirTry to find all jpg/jpeg files using the provided
UploadVulnsWordlist_1593564107766.txt
One of the files happens to be the same uploaded image, so there is a naming scheme
Client-Side filtering bypass
To upload a valid file and bypass client-side filtering, use BurpSuite
Open the homepage at http://jewel.uploadvulns.thm/
Turn on BurpSuite proxy intercept and do a refresh with
SHIFT+F5of the homepageForward until intercepting the
upload.jsscript and right-click to Do intercept Response to this requestRemove the check functions from the response and forward all

Forwarded
upload.js:
Another way is to modify
jewel.jsto make it a JPEG file under 50 KB with the magic numberFF D8 FF DBand a.jpgextension
Upload the
jewel.jpgfile - Successful uploadIt will not work when launched via the Admin page because it is not recognized as a js script
Upload the
jewel.jpgfile - Successful upload because server-side only checks for MIME type (file extension)

Find the file with Gobuster
Opening the file at http://jewel.uploadvulns.thm/content/DQF.jpg with
nclistener, no reverse shell is received

Start a
nclistener on the port setup in thejewel.jspayload fileOpen the found admin page at http://jewel.uploadvulns.thm/admin
try to enter the file name to execute as is
DQF.jpg- not workingtry to use the path to the file
../content/DQF.jpg- Success, received reverse shell
Last updated
Was this helpful?