In this article, we are exploring file upload vulnerabilities from basic to advanced levels, including theoretical concepts and practical examples of seven PortSwigger labs. File upload vulnerabilities are vulnerabilities found in web applications. Attackers can exploit these vulnerabilities by uploading malicious files to a website or web application server and executing their malicious code. Attackers can also achieve remote code execution through file upload vulnerabilities and compromise the entire server.
Types of File Upload Vulnerabilities
Extension-Based File Upload Vulnerabilities
Extension-based file upload vulnerabilities are vulnerabilities that occur when the file upload functionality of a web application is not properly validated. Due to the lack of proper validation, attackers can take advantage of this vulnerability and successfully upload files such as .php, .asp, or .aspx to the server, compromising the entire server.
MIME Type-Based File Upload Vulnerabilities
When we upload a file to a server via a web application interface, the file has a specific MIME type. MIME type-based file upload vulnerabilities occur when the validation of the MIME type is not properly done. Attackers can take advantage of this vulnerability by changing the MIME type of a malicious file and uploading it to the server, compromising the entire server.
File Size-Based File Upload Vulnerabilities
When we upload a file through a web application interface on a server, the file size is usually properly validated, limiting the size of files that can be uploaded. However, file size-based file upload vulnerabilities occur when the file size is not properly validated, allowing attackers to upload a very large file to the server, potentially bringing down the server.
Double Extension-Based File Upload Vulnerabilities
Double extension-based file upload vulnerabilities occur when a web application does not properly verify/validate the extensions of user-uploaded files, allowing attackers to upload their malicious files to the server.
Tampering with the HTTP Request
Tampering with the HTTP request is a type of technique in which an attacker finds vulnerabilities in the HTTP request to exploit the file upload functionality. They exploit these vulnerabilities to upload malicious files.
Bypassing Client-Side and Server-Side Validation
When testing file upload vulns in a web application, attackers will check both client-side and server-side validation. If either is not properly validated, attackers can modify the size, type, and content of their malicious files and bypass validation, compromising the server. Attackers can also modify any parameter in the file upload request to upload their malicious file if the file upload functionality is not properly validated on either the client or server side.
Practical Labs to Bypass File Upload Vulnerabilities
1st lab is Remote code execution via web shell upload
2nd lab is Web shell upload via Content-Type restriction bypass
3rd lab is Web shell upload via path traversal
4th lab is Web shell upload via extension blacklist bypass
5th lab is Web shell upload via obfuscated file extension
6th lab is Remote code execution via polyglot web shell upload
7th lab is Web shell upload via race condition
Remote code execution via web shell upload

Accessing the Lab
So, we are starting to solve the PortSwigger labs, and the first lab we have is ‘Remote code execution via web shell upload’. In this lab, there is a vulnerable image upload function. The developer did not set any kind of validation on this function. To solve the lab, we need to upload a basic PHP web shell to ‘/home/carlos/secret‘. The lab credentials have been provided to us, which are ‘wiener’ and ‘peter’.

First of all, access the lab and log in using the provided credentials of Wiener and Peter.
Uploading a File
After logging in, you will see a file upload interface. Enable your Burp proxy to see the traffic. Upload a simple picture file (provided in the lab) using the file upload function. After uploading, you can see in the screenshot that the image file (simple.png) was successfully uploaded in a POST request. I have highlighted two requests. The first one is a POST request that uploaded the image successfully. The second one is a request to view the uploaded image. Now, go to Burp filtering and enable the image.

I sent both files to the repeater, the first one was a post-based request, where I changed the name to “UplodaImage”. I changed the name of the second request to “ShowImage” because it was a get-based request where the image was being displayed.
Modifying the Payload
Now, I need to modify the content of the post-based request. Since I want to upload my own PHP payload, I will first replace the value of “filename=” with “myexploit.php”. This will result in the final payload looking like this: filename=”myexploit.php”.
Next, I will remove all the raw data of the image that is present below the “Content-Type: image/png” line, as it is unnecessary.

Replacing the Image Data with PHP Payload
In the screenshot, you can clearly see that I removed the data of the simple.png and added my payload data. First, I replaced the name with myexploit.php and then removed the data of the image and added my PHP payload which is our goal to fetch the /home/carlos/secret data to solve the lab.
You can use this payload.
<?php echo file_get_contents('/home/carlos/secret');?>

Submitting the Payload
I simply replaced the ‘simple.png’ with ‘myexploit.php’ and submitted it. And I got the secret key.

Solving the Lab
I submitted myexploit.php instead of simple.png and I got the secret key.

When I submitted the solution key in the lab, the lab was solved. Congratulations!