File Upload
File Upload Vulnerabilities
- File upload vulnerabilities are when a web server allows users to upload files to its filesystem without sufficiently validating things like their name, type, contents, or size.
- Failing to properly enforce restrictions on these could mean that even a basic image upload function can be used to upload arbitrary and potentially dangerous files instead.
- This could even include server-side script files that enable remote code execution.
- In some cases, the act of uploading the file is in itself enough to cause damage. Other attacks may involve a follow-up HTTP request for the file, typically to trigger its execution by the server.
Impact of File Upload Vulnerabilities
Depends on 2 key factors:
- Which aspect of the file the website fails to validate properly, whether that be its size, type, contents, and so on.
- What restrictions are imposed on the file once it has been successfully uploaded.
- Not validate properly and allow certain type of file such as
.phpand.jspto executed as code which leads RCE to gain full control over server.
- If filename is not properly validated then attacker can upload file with same name to overwrite critical file.
- If server is vulnerable to directory traversal then attacker can even upload files to unanticipated locations.
- If server is not checking size of file, then it may leads to DoS attack as attacker can fills available space.
discrepancies : difference b/w 2 things there meaning is same.
How this Vulnerabilities arise?
Developer might attempt to block dangerous file types, but fail to account for parsing discrepancies when checking file extensions. Like for .html there are other extensions is also available.
Also attacker can intercept request and manipulate file type using burp proxy or repeater.
How do web servers handle requests for static files?
- Historically, websites consisted almost entirely of static files that would be served to users when requested. As a result, the path of each request could be mapped 1:1 with the hierarchy of directories and files on the server’s filesystem.
- Nowadays, websites are increasingly dynamic and the path of a request often has no direct relationship to the filesystem at all.
- Nevertheless, web servers still deal with requests for some static files, including stylesheets, images, and so on.
- Server parses the path in the request to identify file extension.
- Then use it to determine file type being requested by comparing it to list of preconfigured mappings between extensions and MIME types.
- If file is non executable such as img or static html page , server may just send file content to client in http response.
- If file is executable such as php file, and if server is configured to execute files of this type, it will assign variables based on the headers and parameters in HTTP requests before running the script. Then result is sent as HTTP response to client.
- If file is executable but server is not configured to execute files of this type, it generally respond with an error. But in some case contents of file may served as plain text such as source code or other sensitive information.
TIP: The
Content-Typeresponse header may provide clues as to what kind of file the server thinks it has served. If this header hasn’t been explicitly set by the application code, it normally contains the result of the file extension/MIME type mapping.
Exploiting unrestricted file uploads to deploy web shell
Worst possible case is server is allows to upload file such as php , Java or Python and is configured to executed them as code. This can leads to create our own web shell on server.
A web shell is a malicious script that enables an attacker to execute arbitrary commands on a remote web server simply by sending HTTP requests to the right endpoint.
If you upload web shell, you will get control over the sever. This means you can read and write arbitrary files, exfiltrate data/files or lateral movement across internal netowork.
Example of PHP one liner to read arbitrary files from server’s filesystem:
1
<?php echo file_get_contents('/path/to/target/file'); ?>
Once this is uploaded, sending request for that malicious file will return target file’s content in the response.
More versatile web shell looks like this:
1
<?php echo system($_GET['command']); ?>
This scripts enables to run arbitrary system command via query parameter:
1
GET /example/exploit.php?command=id HTTP/1.1
Exploiting flawed validation of file uploads
Website has some defenses in place for validation of file type that does not mean they are robust. Attacker can still exploit flaws in mechanism to obtain web shell for RCE.
Flawed File Type Validation
- When submitting HTML forms, the browser typically sends the provided data in a
POSTrequest with the content typeapplication/x-www-form-url-encoded. - This ok with simple text like name or address.
- But not suitable for binary data such as PDF docx.
- In this case, the content type
multipart/form-datais preferred.
Example: Consider form contain upload image along with description and entering username. Submit such as form result in request that looks something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /images HTTP/1.1
Host: normal-website.com
Content-Length: 12345
Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="image"; filename="example.jpg"
Content-Type: image/jpeg
[...binary content of example.jpg...]
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="description"
This is an interesting description of my image.
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="username"
wiener
---------------------------012345678901234567890123456--
- As you can see, the message body is split into separate parts for each of the form’s inputs.
- Each part contains a
Content-Dispositionheader, which provides some basic information about the input field it relates to. - These individual parts may also contain their own
Content-Typeheader, which tells the server the MIME type of the data that was submitted using this input.- Attempt to validate file uploads to check that input specific
Content-Typeheader matches an expectedMIMEtype. - If sever is only allow specific file type such as
image/jpegandimage/png. Problems can arise when value of this header is implicitly trusted by server. - If not further validation is performed to check content of file actually match the supposed
MIMEtype, this can bypassed by burp repeater.
- Attempt to validate file uploads to check that input specific
Preventing file execution in user-accessible directories
- Second line of defense is to stop the server from executing any scripts that do slip through the net.
- As server only run scripts whose MIME type they have explicitly configured to execute.
- Otherwise return error message or server content of file in plaint text instead:
1
2
3
4
5
6
7
8
GET /static/exploit.php?command=id HTTP/1.1
Host: normal-website.com
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 39
<?php echo system($_GET['command']); ?>
- It may provide leak to source code but nullifies any attempt to create web shell.
- This kind of configuration often differs between directories. A directory to which user-supplied files are uploaded will likely have much stricter controls than other locations on the filesystem that are assumed to be out of reach for end users.
- If there is way to upload file in different directory that not supposed to contain user supplied fille, server may execute web shell.
TIPS Web servers often use the
filenamefield inmultipart/form-datarequests to determine the name and location where the file should be saved.
You should also note that even though you may send all of your requests to the same domain name, this often points to a reverse proxy server of some kind, such as a load balancer. Your requests will often be handled by additional servers behind the scenes, which may also be configured differently.
Insufficient blacklisting of dangerous file types
- Example Sometimes developer only block
.phpand not block.php5,.shtml, etc.
Overriding the server configuration
- Servers typically won’t execute files unless they have been configured to do so.
- For example, before an Apache server will execute PHP files requested by a client, developers might have to add the following directives to their
/etc/apache2/apache2.conffile:
1
2
LoadModule php_module /usr/lib/apache2/modules/libphp.so
AddType application/x-httpd-php .php
- Many servers also allow developers to create special configuration files within individual directories in order to override or add to one or more of the global settings.
- Apache servers, for example, will load a directory-specific configuration from a file called
.htaccessif one is present. - developers can make directory-specific configuration on IIS servers using a
web.configfile. - This might include directives such as the following, which in this case allows JSON files to be served to users:
1
2
3
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
- Web servers use these kinds of configuration files when present, but you’re not normally allowed to access them using HTTP requests.
- However, you may occasionally find servers that fail to stop you from uploading your own malicious configuration file.
- In this case, even if the file extension you need is blacklisted, you may be able to trick the server into mapping an arbitrary, custom file extension to an executable MIME type.
One thing to note: .htaccess configurations are applicable only for the same directory and sub-directories where the .htaccess file is uploaded.”
Lab4: Web shell upload via extension blacklist bypass
Obfuscating file extensions
- Even the most exhaustive blacklists can potentially be bypassed using classic obfuscation techniques.
- Like fail to recognize .pHP which is also .php file.
- Mapping of file extension to MIME type is not case sensitive.
- Provide multiple extension. Example:
exploit.php.jpg - Add trailing characters. Some components will strip or ignore like whitespace, dots. Example:
exploit.php - URL encoding (or double URL encoding) for dots, forward and backward slashes.
- If the value isn’t decoded when validating the file extension, but is later decoded server-side, this can also allow you to upload malicious files that would otherwise be blocked:
exploit%2Ephp - Add semicolons or URL-encoded null byte characters before the file extension. If validation is written in a high-level language like PHP or Java, but the server processes the file using lower-level functions in C/C++, for example, this can cause discrepancies in what is treated as the end of the filename:
exploit.asp;.jpgorexploit.asp%00.jpg Some Unicode characters, when processed incorrectly, turn into dots (
.) or null bytes (\0). This can allow attackers to bypass file extension filters.For example:
- Some Unicode sequences look harmless at first (like
xC0 x2E). - But after conversion, they might turn into
.(dot). - This can be used to trick the system into allowing an extension like
.php.
- Some Unicode sequences look harmless at first (like
- Other defenses involve stripping or replacing dangerous extensions to prevent the file from being executed. If this transformation isn’t applied recursively, you can position the prohibited string in such a way that removing it still leaves behind a valid file extension. For example, consider what happens if you strip
.phpfrom the following filename:
1
exploit.p.phphp
Flawed validation of the file’s contents
- Server try to verify contents of file what is expected instead of implicitly trusting the
Content-Type. - In the case of an image upload function, the server might try to verify certain intrinsic properties of an image, such as its dimensions. If you try uploading a PHP script, for example, it won’t have any dimensions at all. Therefore, the server can deduce that it can’t possibly be an image, and reject the upload accordingly.
- Certain file types may always contain a specific sequence of bytes in their header or footer. These can be used like a fingerprint or signature to determine whether the contents match the expected type. For example, JPEG files always begin with the bytes
FF D8 FF. - Tools like
ExifTool, it can be possible create a polyglot JPEG file containing malicious code within its metadata.
Exploiting File Upload Race Conditions
- Modern Framework do send image to sandbox , change name randomly and save it to intended destination to avoid overwriting existing files.
- Many times developer implement their own processing file uploads independent of any framework. It introduce race conditions that can even bypass most robust validation.
- For example, some websites upload the file directly to the main filesystem and then remove it again if it doesn’t pass validation. This kind of behavior is typical in websites that rely on anti-virus software and the like to check for malware. This may only take a few milliseconds, but for the short time that the file exists on the server, the attacker can potentially still execute it.
- These vulnerabilities are often extremely subtle, making them difficult to detect during blackbox testing unless you can find a way to leak the relevant source code.
Race Conditions in URL-based file uploads
- Similar race conditions can occur in functions that allow you to upload a file by providing a URL.
- The server has to fetch the file over the internet and create a local copy before it can perform any validation.
- As the file is loaded using HTTP, developers are unable to use their framework’s built-in mechanisms for securely validating files.
- Instead, they may manually create their own processes for temporarily storing and validating the file, which may not be quite as secure.
- For example, if the file is loaded into a temporary directory with a randomized name, in theory, it should be impossible for an attacker to exploit any race conditions.
- If they don’t know the name of the directory, they will be unable to request the file in order to trigger its execution. On the other hand, if the randomized directory name is generated using pseudo-random functions like PHP’s
uniqid(), it can potentially be brute-forced. - To make attacks like this easier, you can try to extend the amount of time taken to process the file, thereby lengthening the window for brute-forcing the directory name.
- One way of doing this is by uploading a larger file. If it is processed in chunks, you can potentially take advantage of this by creating a malicious file with the payload at the start, followed by a large number of arbitrary padding bytes.
Exploiting file upload vulnerabilities without remote code execution
Uploading malicious client-side scripts
- Although you might not be able to execute scripts on the server, you may still be able to upload scripts for client-side attacks. For example, if you can upload HTML files or SVG images, you can potentially use
<script>tags to create stored XSS payloads. - If the uploaded file then appears on a page that is visited by other users, their browser will execute the script when it tries to render the page. Note that due to same-origin policy restrictions, these kinds of attacks will only work if the uploaded file is served from the same origin to which you upload it.
Exploiting vulnerabilities in the parsing of uploaded files
- If the uploaded file seems to be both stored and served securely, the last resort is to try exploiting vulnerabilities specific to the parsing or processing of different file formats.
- For example, you know that the server parses XML-based files, such as Microsoft Office
.docor.xlsfiles, this may be a potential vector for XXE injection attacks.
Uploading files using PUT
- It’s worth noting that some web servers may be configured to support
PUTrequests. If appropriate defenses aren’t in place, this can provide an alternative means of uploading malicious files, even when an upload function isn’t available via the web interface.
1
2
3
4
5
6
PUT /images/exploit.php HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-httpd-php
Content-Length: 49
<?php echo file_get_contents('/path/to/file'); ?>
TIPS: You can try sending
OPTIONSrequests to different endpoints to test for any that advertise support for thePUTmethod.
Preventions
- Check the file extension against a whitelist of permitted extensions rather than a blacklist of prohibited ones. It’s much easier to guess which extensions you might want to allow than it is to guess which ones an attacker might try to upload.
- Make sure the filename doesn’t contain any substrings that may be interpreted as a directory or a traversal sequence (
../). - Rename uploaded files to avoid collisions that may cause existing files to be overwritten.
- Do not upload files to the server’s permanent filesystem until they have been fully validated.
- As much as possible, use an established framework for preprocessing file uploads rather than attempting to write your own validation mechanisms.
