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

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 .png file and check correct uploading at http://java.uploadvulns.thm/images

    • (2nd option: prevent client-side-filter.js file from being loaded by intercepting the response with Burp)

  • Change php-reverse-shell.php extension and catch the upload request with BurpSuite

    • as 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 filename and the Content-Type to the following values and then forward the request


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


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.


Final challenge - Jewel

  • Check source code and the available .js files

  • 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 .jpg or .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.jpg from the /content dir

  • Try 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+F5 of the homepage

    • Forward until intercepting the upload.js script and right-click to Do intercept Response to this request

    • Remove the check functions from the response and forward all

  • Forwarded upload.js:

  • Another way is to modify jewel.js to make it a JPEG file under 50 KB with the magic number FF D8 FF DB and a .jpg extension

  • Upload the jewel.jpg file - Successful upload

  • It will not work when launched via the Admin page because it is not recognized as a js script

  • Upload the jewel.jpg file - Successful upload because server-side only checks for MIME type (file extension)

  • Find the file with Gobuster

  • Start a nc listener on the port setup in the jewel.js payload file

  • Open the found admin page at http://jewel.uploadvulns.thm/admin

    • try to enter the file name to execute as is DQF.jpg - not working

    • try to use the path to the file ../content/DQF.jpg - Success, received reverse shell


Last updated

Was this helpful?