File Upload Vulnerabilities

Categories

  • File Upload vulnerabilities can be divided into three categories:

    • Executable: Consists of vulnerabilities enabling us to upload files that are executable by the web application. For example, if we can upload a PHP script to a web server where PHP is enabled, we can execute the script by accessing it via the browser or curl.

    • Combined: Vulnerabilities that require us to combine the file upload mechanism with another vulnerability, such as Directory Traversal. For example, if the web application is vulnerable to Directory Traversal, we can use a relative path in the file upload request and try to overwrite files like authorized_keys. Furthermore, we can also combine file upload mechanisms with XML External Entity (XXE) or Cross Site Scripting (XSS) attacks. For example, when we are allowed to upload an avatar to a profile with an SVG file type, we may embed an XXE attack to display file contents or even execute code.

    • Based on User Interaction: Vulnerabilities that relies on user interaction. For example, when we discover an upload form for job applications, we can try to upload a CV in .docx format with malicious macros integrated.

Identifying File Upload Vulnerabilities

  • Depending on the web application and its usage, we can make educated guesses to locate upload mechanisms.

  • If the web application is a Content Management System (CMS), we can often upload an avatar for our profile or create blog posts and web pages with attached files.

  • If our target is a company website, we can often find upload mechanisms in career sections or company-specific use cases.

  • When we identify a file upload function, we can start working on exploiting it.

Exploiting

  • Let's say we found a function to upload an image, first of all, we should try uploading a test file, say for example a .TXT file.

  • If the upload is successful then we move into the next step which is trying to upload a backdoor. For example, a PHP remote shell.

  • If the upload failed for either, we start analyzing and trying to understand how the filter is implemented. For example, is it based on the extension alone or other filtering techniques as well?

  • If it's based on the extension, we can try changing the file extension to a less-commonly used PHP file extension such as .phps or .php7

  • Another way we can bypass the filter is by changing characters in the file extension to upper case. The blacklist may be implemented by comparing the file extension of the uploaded file to a list of strings containing only lower-case PHP file extensions. If so, we can update the uploaded file extension with upper-case characters to bypass the filter.

  • It is important to understand that while the implementation of a web shell is dependent on the programming language, the basic process of using a web shell is nearly identical across these frameworks and languages.

  • Web applications handling and managing files often enable users to rename or modify files. We could abuse this by uploading a file with an innocent file type like .txt, then changing the file back to the original file type of the web shell by renaming it.

  • Web applications using Apache, Nginx or other dedicated web servers often run with specific users, such as www-data on Linux.

  • Traditionally on Windows, the IIS web server runs as a Network Service account, a passwordless built-in Windows identity with low privileges. Starting with IIS version 7.5, Microsoft introduced the IIS Application Pool Identities. These are virtual accounts running web applications grouped by application pools. Each application pool has its own pool identity, making it possible to set more precise permissions for accounts running web applications.

  • When using programming languages that include their own web server, administrators and developers often deploy the web application without any privilege structures by running applications as root or Administrator to avoid any permissions issues. This means we should always verify whether we can leverage root or administrator privileges in a file upload vulnerability.

Example/Walkthrough:

  • First, explore the website by going to the site itself.

  • Try to understand what system the website is running on, for example, try to curl index.php or try to enumerate files on the website.

  • When testing a file upload form, we should always determine what happens when a file is uploaded twice. If the web application indicates that the file already exists, we can use this method to brute force the contents of a web server. Alternatively, if the web application displays an error message, this may provide valuable information such as the programming language or web technologies in use.

  • Review the upload request in Burp.

  • Check if the web application allows us to specify a relative path in the filename and write a file via Directory Traversal outside of the web root. We can do this by modifying the "filename" parameter in the request so it contains ../../../../../../../test.txt (Getting status code 200 doesn't mean that it worked. Unfortunately, we have no way of knowing if the relative path was used for placing the file. It's possible that the web application's response merely echoed our filename and sanitized it internally)

  • If the directory traversal worked, we can try to blindly overwrite files, which may lead us to system access. We should be aware, that blindly overwriting files in a real-life penetration test could result in lost data or costly downtime of a production system.

  • An example of how we can utilize the directory traversal file upload vulnerability is by overwriting the authorized_keys file in the home directory for root. If this file contains the public key of a private key we control, we can access the system via SSH as the root user.

    • To do this, we'll create an SSH keypair with ssh-keygen, as well as a file with the name authorized_keys containing the previously created public key.

    • Now that the authorized_keys file contains our public key, we can upload it using the relative path ../../../../../../../root/.ssh/authorized_keys.

    • If we've successfully overwritten the authorized_keys file of the root user, we should be able to use our private key to connect to the system via SSH (ssh -p 2222 -i PrivateKey root@<Website>). We should note that often the root user does not carry SSH access permissions so we should try and do this attack on another users.

Last updated