Fundamentals & Lab Environment Setup Lesson 1 of 11
In Progress

File Upload Vulnerabilities: Core Concepts, Attack Vectors & Risks

File upload vulnerability is a type of vulnerability that allows an attacker to upload malicious files to a website, which can then be executed on the server or used to compromise the website. This type of vulnerability can be found in web applications that allow users to upload files, such as file upload forms or forums that allow users to upload images or attachments. 

An attacker can exploit this vulnerability by uploading a malicious file, such as a script or executable, which can then be executed on the server or used to gain unauthorized access to the website.

In this chapter, we will delve into the critical aspect of web application security concerning file uploads. Chances are, most of you have come across web applications that offer the convenient functionality of file upload, often in the form of images, videos, documents, and more.

However, if a web application has poor (or no) security mechanisms to prevent certain kinds of files, such as server-side scripting, then that can result in arbitrary code execution on the server. Even with limited file upload capability, we can execute arbitrary JS (XSS), and CSRF, and run client-side exploits.

How to prevent file upload vulnerabilities? 

To prevent file upload vulnerabilities, it is important to properly validate the file type, size, and content of any file that is uploaded to the server. This can help to ensure that only safe files are allowed to be uploaded and executed on the server.
Reading Material
Fundamentals & Lab Environment Setup Lesson 2 of 11
In Progress

Introduction to File Upload Flaws and Secure Coding Principles

File upload vulnerability is a type of vulnerability that allows an attacker to upload malicious files to a website, which can then be executed on the server or used to compromise the website. This type of vulnerability can be found in web applications that allow users to upload files, such as file upload forms or forums that allow users to upload images or attachments.

An attacker can exploit this vulnerability by uploading a malicious file, such as a script or executable, which can then be executed on the server or used to gain unauthorized access to the website. The uploaded file can also be used to gain unauthorized access to sensitive information, steal user data, or launch a distributed denial-of-service (DDoS) attack.

The vulnerability can occur due to several reasons: 

  • Inadequate validation of the file type and extension
  • Inadequate validation of the file size
  • Inadequate validation of the file content
  • Inadequate validation of the file name
  • Inadequate validation of the file metadata
  • Misconfigured file permissions
  • Misconfigured server configurations
  • Inadequate file upload handling and processing
  • Inadequate error handling

There are several types of attacks that can be used to exploit file upload vulnerabilities. For example, an attacker may try to upload a file that contains malicious code, such as a PHP script or an executable file. The attacker could then access the file from the server and execute the code, potentially gaining access to sensitive data or taking control of the server.

Another type of attack that can be used to exploit file upload vulnerabilities are called "cross-site scripting" (XSS). This type of attack involves injecting malicious code into a website, which is then executed by the victim's web browser. If a user is tricked into uploading a file that contains XSS code, the code could be executed on the server and potentially compromise the security of the system.

How to prevent File upload vulnerability?

There are several ways to prevent file upload vulnerabilities in PHP code:

  1. File type validation: Use the PHP function mime_content_type() to validate the file type before uploading. This will ensure that only the allowed file types are uploaded.
  2. File extension validation: Use the PHP function pathinfo() to check the file extension and only allow certain extensions.
  3. File size validation: Use the PHP function filesize() to check the file size and only allow files within a certain size limit.
  4. File content validation: Use the PHP function file_get_contents() to check the file content for malicious code before uploading.
  5. File name validation: Use the PHP function preg_match() to check the file name for characters that could be used to exploit vulnerabilities.
  6. File metadata validation: Use the PHP function exif_read_data() to check for malicious metadata in the file.
  7. File permission validation: Use the PHP function chmod() to set appropriate permissions on the uploaded file to prevent unauthorized access.
  8. File upload handling and processing: Use the PHP function move_uploaded_file() to move the uploaded file to a secure location, and rename the file to prevent overwriting existing files.
  9. Error handling: Use the PHP function error_log() to log any errors that occur during the file upload process, and use the PHP function die() to stop the script execution if an error occurs.

It's also worth mentioning that it is important to keep the PHP version up to date as well as any library or framework used by the application to prevent known vulnerabilities.

It is important to note that these are general guidelines and that specific implementation details may vary depending on the specific requirements of the application. It is recommended to use a well-vetted library that handles file uploads securely.

Fundamentals & Lab Environment Setup Lesson 3 of 11
In Progress

What is DVFU Lab & Setting Up the Damn Vulnerable File Upload Lab

File upload vulnerabilities occur when an application allows a user to upload a file, such as a picture or a document, to a server. If the application does not correctly validate the file, an attacker may be able to upload a malicious file that could compromise the server's security. This can allow the attacker to execute arbitrary code on the server, or to access sensitive information stored on the server.

Several types of attacks can be used to exploit file upload vulnerabilities. For example, an attacker may try to upload a file that contains malicious code, such as aPHP scriptor anexecutable file. The attacker could then access the file from the server and execute the code, potentially gaining access to sensitive data or taking control of the server.

Another type of attack that can be used to exploit file upload vulnerabilities are called "cross-site scripting" (XSS). This type of attack involves injecting malicious code into a website, which is then executed by the victim's web browser. If a user is tricked into uploading a file that contains XSS code, the code could be executed on the server and potentially compromise the security of the system.

Set up DVFU

Let's go straight to demonstrate file upload vulnerability using the Damn Vulnerable File Upload Lab web application. Damn Vulnerable File Upload Lab is designed to practice File Upload vulnerabilities. Before getting started, our first priority is to set up this web application within our local machine.

Follow the below steps to set up the server:

1. To set up the File Upload Lab web application, firstly, we have to clone it from GitHub. 

┌──(kali㉿kali)-[~]
└─$git clone https://github.com/LunaM00n/File-Upload-Lab.git
Cloning into 'File-Upload-Lab'...
remote: Enumerating objects: 182, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 182 (delta 13), reused 13 (delta 13), pack-reused 167
Receiving objects: 100% (182/182), 895.80 KiB | 202.00 KiB/s, done.
Resolving deltas: 100% (74/74), done.
┌──(kali㉿kali)-[~]
└─$

2. Now, we will have to copy the DVFU directory to the web directory. 

┌──(kali㉿kali)-[~]
└─$ls                        # To List Files and Directories
Desktop  Documents  Downloads File-Upload-Lab  Music  Pictures  Public  Templates  Videos
┌──(kali㉿kali)-[~]
└─$cd File-Upload-Lab       # Change The Directories to File Upload Lab 
┌──(kali㉿kali)-[~/File-Upload-Lab]
└─$ls                       # To List Files and Directories
 DVFU  'File Upload Attack.pdf'   README.md   tester.php
┌──(kali㉿kali)-[~/File-Upload-Lab]
└─$sudo cp -r DVFU /var/www/html       # Copy the DVFU directories to web Directories
[sudo] password for kali: 
┌──(kali㉿kali)-[~/File-Upload-Lab]
└─$ cd /var/www/html                   # Change the Directories to Web Directories
┌──(kali㉿kali)-[/var/www/html]
└─$ls -al                   # List the Files and directories
total 28
drwxr-xr-x 3 root root  4096 Jan  9 10:45 .
drwxr-xr-x 3 kali kali  4096 Aug  8 06:05 ..
drwxr-xr-x 5 root root  4096 Jan  9 10:45 DVFU
-rw-r--r-- 1 root root 10701 Aug  8 06:09 index.html
┌──(kali㉿kali)-[/var/www/html]
└─$sudo chmod -R 777 DVFU       # Give an executable File Permission to DVFU
┌──(kali㉿kali)-[/var/www/html]
└─$

3. Now, let me run the apache2 service.

┌──(kali㉿kali)-[/var/www/html]
└─$sudo service apache2 start

4. Once the Apache2 service starts, we can easily access the web application through any browser.

If you have noticed, we are presented with various levels of an HTML form that asks us to upload a file.

Extension Filter Bypasses & Client-Side Validation Lesson 4 of 11
In Progress

Level 1: Unrestricted File Upload & Initial Web Shell Execution

Let's visit the Level 1 section, and see if we can upload and run our own PHP script on the backend:

In this section, there will be no security restrictions, so it means, we can upload malicious files. Let’s see if we can upload and run our own PHP script on the backend. 

<?php
     $files = @$_FILES["files"];
     if ($files["name"] != '') {
         $fullpath = $_REQUEST["path"] . $files["name"];
         if (move_uploaded_file($files['tmp_name'], $fullpath)) {
             echo "<a href='$fullpath'>uploaded image</a>";
             }
          }
         echo '<form method=POST enctype="multipart/form-data" action="">
               <input type="file" name="files">
               <input type=submit value="Upload File"></form>';
 ?>
<?php
echo phpinfo();
?>

Let's create a simple PHP file containing the following code, which displays the PHP information.

The preceding code executes the phpinfo() when executed by a PHP interpreter. We use this to check if the uploaded PHP file is successfully executed on the server side or not.

We get a successful upload message and path information for the file as well. Let's try to access the file to see if PHP code execution is possible on the server.

Look at that! Our PHP code ran on the server successfully. This payload was benign and only intended for testing. 

Extension Filter Bypasses & Client-Side Validation Lesson 5 of 11
In Progress

Level 2: Bypassing Basic Blacklist Extension Checks (.php5, .phtml, .php3)

Let’s move on to the 2nd Level section. 

In this section, there will be some sort of protection mechanisms to prevent PHP file uploads, which means, we can’t upload dot PHP file extension.

Developers, sometimes, add a blacklist for certain file extensions, which is considered harmful. 

<?php
$files = @$_FILES["files"];
$info = new SplFileInfo($files["name"]);
$extension=($info->getExtension());
if ($files["name"] != '' && $extension !="php") {
$fullpath = $_REQUEST["path"] . $files["name"];
if (move_uploaded_file($files['tmp_name'], $fullpath)) {
echo "<a href='$fullpath'>OK-Click here!</a>";
}
}
echo '<form method=POST enctype="multipart/form-data" action=""><input type="file" name="files"><input type=submit value="Upload File"></form>';
?>

But, we can try to do this with other .php extensions. 

  • Supported PHP File Extension
    • .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module
  • Working in PHPv8: 
    • .php, .php4, .php5, .phtml, .module, .inc, .hphp, .ctp

As running the Apache2 service supports PHPv8, so rename the file to the .phtml file.

Now, we will upload this file and see whether it is uploaded successfully or not.

Let's try to access the file to see if PHP code execution is possible on the server. 

Once we click on "Upload File", open the uploaded link:

Look at that! Our PHP code ran on the server successfully.

Extension Filter Bypasses & Client-Side Validation Lesson 6 of 11
In Progress

Level 3: Advanced Blacklist Bypass (Case sensitivity, double extensions, trailing dots & spaces)

Similar to the previous level, Level 3 is also the same, where Developers add a blacklist for the PHP file extension and its other variants but forgot to do something to blacklist.

In this section, Developer adds a blacklist for certain file extensions but forgets something to restrict, which is considered harmful.

<?php
$files = @$_FILES["files"];
$info = new SplFileInfo($files["name"]);
$extension=($info->getExtension());
if ($files["name"] != '' && $extension != "php" && $extension != "php3" && $extension != "jpeg" && $extension != "png" && $extension != "gif") {
$fullpath = $_REQUEST["path"] . $files["name"];
if (move_uploaded_file($files['tmp_name'], $fullpath)) {
echo "<a href='$fullpath'>OK-Click here!</a>";
}
}
echo '<form method=POST enctype="multipart/form-data" action=""><input type="file" name="files"><input type=submit value="Upload File"></form>';
?>

Let’s try to upload the previous file extension to see if this file uploaded successfully or not.

Click on "phpinfo.phtml" and click on open.

Now, we will upload this file and see whether it is uploaded successfully or not.


Once uploaded, open the UPLOADED link in another tab.

Look at that! Our PHP code ran on the server successfully. This payload was benign and only intended for testing. 

MIME Type, Server Handlers & Image Header Bypasses Lesson 7 of 11
In Progress

Level 4: MIME Content-Type Verification Bypass using Burp Suite

Let’s move on to Level 4

In this section, if we try to upload our previous file, we receive the following error, which means, we can only upload the .gif file extension.

Every document or file has a valid MIME type, which is an identifier consisting of two parts, a type, and a subtype, separated by a forward slash. Web developers, at times, rely on the MIME type of the uploaded file to verify whether it's a safe file or not. For an image upload application, the allowed MIME types can beimage/jpegimage/gif, andimage/png

The following PHP code only allows GIF files by verifying the file's MIME type during the upload process:

<?php
if($_FILES['uploadedfile']['type'] != "image/gif") {
if(isset($_FILES['uploadedfile'])){echo "Sorry, GIF only!";}
 exit;
}
$uploaddir = 'uploads/';
 $uploadfile = $uploaddir . basename($_FILES['uploadedfile']['name']);
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploadfile)) {
 echo "File is valid, and was successfully uploaded.\n";
 } else {
echo "File uploading failed.\n";
}
?>

<?php 
if($uploadfile!= '') { echo "<a href=\"$uploadfile\">Uploaded</a>"; } 
?>

Let’s try to upload this file(phpinfo.php) after changing its file extension to gif

Now, let’s try to upload it again. 

As you can notice, the upload was successful. 

Let’s try to open this link. 

The upload was successful, but the uploaded file not running as a PHP file, as the file acts as a gif file. We can bypass this check by simply changing the MIME type through an intercepting Proxy

Launch Burp Suite from the application menu.

Tap on the Proxy tab, and turn on intercepting mode. 

Now, go back to the Firefox browser and change the proxy setting to Burp suite using the Foxy Proxy extension.


Now, let's try to upload the gif file again. Once, we click on the upload button, we will automatically intercept HTTP headers.

Here, we will have to change the file name to .php extension. 

If you have noticed, the MIME-type is an image and the subtype is a gif. 

Once we forward the headers, we will receive a successful upload message. Since, this time, the MIME type matches one of the image file's MIME types, we successfully bypassed this check and uploaded the file to the server.

As you can notice, we have received the successful upload message. Once uploaded, open the UPLOADED link in another tab.

Look at that! Our PHP code ran on the server successfully. This payload was benign and only intended for testing.

MIME Type, Server Handlers & Image Header Bypasses Lesson 8 of 11
In Progress

Level 5: Apache's .htaccess Override Trick to Execute Benign Files as PHP

Let’s move on to the Level 5 section. 

In this section, if we try to upload the .php file, we will receive the following error message. 

Let’s try to upload "phpinfo.php" again after changing the content type. 

But similar to the previous, we have received the same problem.

If we try to upload a gif file, we will receive a successful upload message. 

Since, the uploaded file is in form of image format, which means it can’t run as a PHP file.

Similar to the previous level, if we try to change the file format name to PHP, we will receive a similar "Failed" message. 

The following PHP code does not allow HTML, or PHP files during the upload process:

<?php
$blacklist = array(".php","html","shtml",".phtml", ".php3", ".php4",".php7");
foreach ($blacklist as $item) {
if(preg_match("/$item\$/", $_FILES['uploadedfile']['name'])) {
 if(isset($_FILES['uploadedfile'])){echo "We do not allow HTML , PHP files\n";}
exit;
               }
        }
$uploaddir = 'uploads/';
 $uploadfile = $uploaddir . basename($_FILES['uploadedfile']['name']);
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
}
 ?>
 <?php if($uploadfile!= '') { echo "<a href=\"$uploadfile\">Uploaded</a>"; } ?>

There are two ways in which we can trick Apache to execute a file with a safe extension as PHP. 

  • TheSetHandler method
  • TheAddTypemethod

Using Set Hander Method

We uploaded the following.htaccessfile, which tricks Apache to execute any file containing ".gifas a valid PHP file by forcing through theSetHandler directive:

Open a text editor and type the following code. 

Now save it as .htaccess

Remember to save this file in a fresh directory(like Download, Document), where there will be no hidden files and directories.

Now, We will have to upload the .htaccess file, which tricks Apache to execute any file containing .gif as a valid PHP file by forcing through the SetHandler directive.

Now, we upload the file with the name phpinfo.gif

Once it is uploaded, we can access the file.

As you can notice, this safe .gif file gets executed as a valid PHP file.

Using the AddType method

Similar to the SetHandler method, here, we instead map a new file extension, such as .lol, which gets executed as a PHP file.

To achieve this, we upload the following as the .htaccess file.

Then we upload a file with .lol as the file extension, say phpinfo.lol, and then, access the file from a browser.

Observe the file extension in the URL, it's .lol, which gets mapped to PHP and is executed accordingly.

MIME Type, Server Handlers & Image Header Bypasses Lesson 9 of 11
In Progress

Level 6: Bypassing Image Content Verification (Magic Bytes & GIF89a Header Injection)

Let’s move on to the Level 6 section. 

Here, If we try to upload any file which contains PHP and HTML codes can easily be detected.

In this section, there's a function, called getimagesize() function, which basically reads a file, and returns the size of the image, if a correct image file is provided. In case an invalid file is thrown, then the getimagesize() function silently fails. The property of this function is used to verify if the file is an image or not.

However, there are techniques that can effectively lead to the bypass of this protection. Consider the following PHP code, which uploads the file whengetimagesize() passes through and returns an error in case of an invalid image file is tried for upload:

<?php
$imageinfo = getimagesize($_FILES['uploadedfile']['tmp_name']);
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') {
if(isset($_FILES['uploadedfile'])){echo "Sorry, we only accept GIF and JPEG images\n";}
exit;
}
$uploaddir = 'uploads/';
$uploadfile = $uploaddir . basename($_FILES['uploadedfile']['name']);
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "File uploading failed.\n";
}
?>
<?php if($uploadfile!= '') { echo "<a href=\"$uploadfile\">Uploaded</a>"; } ?>

However, there are techniques that can effectively lead to the bypass of this protection. We can easily bypass such checks by adding the Magic code of the same file extension.

You can find out the proper magic code below the link: 

Copy the GIF signature code on "phpinfo.gif".

Now, the file should get uploaded without any problems. But, we will have to modify the file name to .php through Burp Suite.

Now, we shall go ahead and access the file. 

Look at that! Our valid GIF file containing our PHP script was uploaded successfully and was executed as expected. 

So, here, we've successfully defeated the getimagesize() function and uploaded our payload.

Stored XSS, Reverse Shells & Hardening Lesson 10 of 11
In Progress

Level 7: Stored Cross-Site Scripting (XSS) via Malicious SVG / HTML Uploads

Let’s move on to the Level 7 section. 

Here, in this section, if we try to upload any file, then we will not receive any link, on which the file is uploaded.

The following PHP code will allow XSS files. But, we can find out the file location using cross-site scripting file upload vulnerability. 

 <?php
$files = @$_FILES["files"];
if ($files["name"] != '') {
$fullpath = $_REQUEST["path"] . $files["name"];
$filename=$files["name"];
if (move_uploaded_file($files['tmp_name'], $fullpath)) {
echo "Uploaded ".$filename;
}
else
echo "Error with this file".$filename;
}
echo '<form method=POST enctype="multipart/form-data" action="">
                      <input type="file" name="files">
                      <input type=submit value="Upload File"></form>';
?>

Save a file with the following cross-site scripting code. 

Now, upload it. Once we upload this file, we will prompt us with the domain name. 

Let’s try to find out, there will be the uploaded file are located. 

The file is uploaded within this same directory.

Let me change this PHP file name to the PHP info file. 

As expected, we have successfully accessed the PHP file.

Reading Material
Stored XSS, Reverse Shells & Hardening Lesson 11 of 11
In Progress

Netcat Accessible PHP Reverse Shell & Remote Server Takeover

Netcat is often called the Swiss Army knife of hackers and penetration testers. Netcat allows reading/writing to TCP/UDP connections and has a large set of functionalities, ranging from port scans to file transfer mechanisms. However, here, we'll use Netcat to access a reverse shell. 

First, we'll need a PHP script that is capable of creating TCP connection-based reverse shells. Open a new terminal and copy the php-reverse-shell command. 

┌──(kali㉿kali)-[~]
└─$cp /usr/share/webshells/php/php-reverse-shell.php .

After this, we have to configure the reverse shell PHP file by providing a proper IP and port, so that it can connect with the NetCat listener.

Once the php-reverse-shell.php file is configured, upload the file:

Before that we initiate the reverse shell, we need to create our NetCat listener. Let's create a listener on port 1234.

┌──(kali㉿kali)-[~]
└─$nc -lvnp 1234

As soon as we click on the link, our Netcat gets a reverse shell from the server, and we can happily execute commands through this interactive command shell.

This continuous reverse shell is very useful when we want to exploit further into other systems or execute a privilege escalation exploit.

Fundamentals & Lab Environment Setup Quiz

File Upload Fundamentals Quiz

2 questions • Test your knowledge

Question 1
What is the most critical risk associated with an unvalidated file upload vulnerability on a web server?
Question 2
Why is client-side JavaScript validation (e.g. checking file extensions in the browser) completely ineffective as a standalone security control?
Extension Filter Bypasses & Client-Side Validation Quiz

Extension Filtering & Bypasses Quiz

2 questions • Test your knowledge

Question 1
Why is a "Blacklist" approach to file extensions (blocking only .php) fundamentally flawed in web application security?
Question 2
How can case-sensitivity differences between the application code and the web server/OS be exploited to bypass extension checks?
MIME Type, Server Handlers & Image Header Bypasses Quiz

MIME, .htaccess & Magic Bytes Quiz

3 questions • Test your knowledge

Question 1
Where does the HTTP "Content-Type" header originate during a file upload, and why can it not be trusted by the server?
Question 2
How can uploading a custom `.htaccess` configuration file lead to code execution if the server blocks PHP file extensions?
Question 3
What are "Magic Bytes" in file format verification?
Stored XSS, Reverse Shells & Hardening Quiz

Stored XSS & Reverse Shells Quiz

2 questions • Test your knowledge

Question 1
Why can uploading an SVG (Scalable Vector Graphics) image file result in Stored Cross-Site Scripting (XSS)?
Question 2
What is the most comprehensive defense against file upload vulnerabilities?
High-Resolution Preview