IL Exercise 21: Unrestricted File Uploads

This exercise explores the threat posed by file uploads in web applications that don’t perform sufficient checking of what is uploaded. The Immersive Labs platform is used, so make sure you have set up access before you begin.


  1. Login to Immersive Labs and start the Unrestricted File Upload lab. While you wait for the Linux VMs to spin up, click on the Info button at the top-right of the screen and read the contents of the information panel.

  2. When the Kali Linux VM desktop is visible, click the Network button to open the network information panel. Note the IP address of the target.

  3. Double-click on the desktop icon to run Burp Suite. Accept the terms & conditions, choose the options to create a temporary project and use Burp defaults, then click the Start Burp button.

    When Burp is running, select the Proxy tab and click the button to disable interception of HTTP requests and responses. (You will enable interception later to facilitate the attack, but disabling it for now will make exploring the vulnerable web application easier.)

Exploring the Application

  1. Start a terminal window. Enter the following commands to run the Chromium browser, specifying Burp as its web proxy:

    export http_proxy=

    When Chromium is running, enter the target’s IP address in the browser address bar to visit the vulnerable web application. Click on the ‘Album’ link to view the image gallery. There should be three images visible. Click the ‘Home’ link to return to the home page.

  2. Now experiment with uploading an image. Click the Browse button on the home page and navigate to /usr/share/images/kali-logos. Choose the file logo-256.png, then click the Upload Image button back on the home page to perform the upload. The gallery should now have four images.

    When you’ve finished experimenting, return to the application’s home page.

Initial Attempts

  1. Let’s try injecting a PHP script to steal the contents of the password file. In the terminal window, enter the command nano script.php to start a text editor1. Enter the following code:

    echo "\n" . file_get_contents("/etc/passwd");

    Press Ctrl+O to save the file, then Ctrl+X to exit.

  2. Try to upload script.php to the web application. What happens?

  3. We need to modify the content type of the uploaded file, so that the web application will think it is an image. We will use Burp Suite for this, since we are already proxying all web requests through it.

    In Burp Suite, go to the Proxy tab and click the button to begin intercepting requests and responses.

  4. Back in Chromium, click the Browse button and select script.php, then click Upload Image.

    Go back to Burp. Select the Intercept tab to see the details of the HTTP request being made by the browser. Edit the ‘Content-Type’ field to have the value image/gif, then click the Forward button to forward the modified request from Burp to the web server.

    How does the web application respond?

A Successful Attack

  1. The web application is doing some rudimentary checking of uploaded files by checking file signatures (sometimes referred to as ‘magic numbers’). A file signature is a sequence of bytes at the start of a file that serves to identify the type of file we are dealing with. To make our script look more like a GIF image, we need to add appropriate file signature bytes to the start of the file.

    Edit the script again with nano script.php. Add the characters GIF89a to the start of the file. Your script should now look like this:

    echo "\n" . file_get_contents("/etc/passwd");

    Save the file and exit.

  2. Use the Browse and Upload Image buttons of the application to select and upload script.php, as you attempted to do previously.

    In Burp, edit ‘Content-Type’ to image/gif as you did before, then click the Forward button to do the upload, which should now succeed.

    Click Forward two more times: once for the GET request that reloads the gallery page, then once for the GET request that is supposed to retrieve the newly-uploaded image, but in fact runs our script.

  3. In Burp, go to the HTTP History tab and select the final GET request (the one that ran the uploaded script on the server). Click on the Response tab to view the details of the reponse to the GET request. You should see the contents of /etc/passwd listed!

  1. Vim is available in Kali Linux, if you prefer to use that instead. ↩︎