Exploiting File Upload Vulnerabilities with DVWA

This exercise explores vulnerabilities associated with file uploads. The target machine was the Damn Vulnerable Web Application (DVWA) found at http://www.dvwa.co.uk/ however, this web application came preinstalled with Metasploitable 2 found at https://information.rapid7.com/metasploitable-download.html.

DVWA, according to its website, “is a PHP/MySQL web application that is damn vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, help web developers better understand the processes of securing web applications and aid teachers/students to teach/learn web application security in a classroom environment” (http://www.dvwa.co.uk/).

Metasploitable “is virtual machine based on Linux that contains several intentional vulnerabilities for you to exploit. Metasploitable is essentially a penetration testing lab in a box, available as a VMware virtual machine (VMX),” (https://information.rapid7.com/metasploitable-download.html).

The attacker machine used, as always, was Kali Linux, found at https://www.kali.org. For this exploit, I opted to use VirtualBox from Oracle instead of the Microsoft Hyper-V platform. VirtualBox can be downloaded from https://www.virtualbox.org/wiki/Downloads.

For this test, it was paramount to ensure that both Kali and Metasploitable were running on the same NAT network. To check, I simply ran the ifconfig command, as both machines run on Linux. However, in order to authenticate to Metasploitable, I had to login using the default username and password msfadmin.

Confirm IP MS.jpg

Confirm IP Kali.jpg

Next, I navigated to 10.0.2.4 in the web browser to access Metasploitable.

Navigate to MS.jpg

Once open, I navigated to the DVWA page. I was directed to the login page. The default username is admin and the default password is password.

DVWA Login.jpg 

Username admin pw password.jpg

Next, I navigated to the upload page to see if I was able to successfully upload an image to the server.

Upload File.jpg

Successful Image Upload.jpg

Navigate to Upload.jpg

Using Weevely (a tool that comes preinstalled in the Kali Linux distribution, I created a backdoor shell command. According to the Kali Linux documentation, “Weevely is a stealth PHP web shell that simulate telnet-like connection. It is an essential tool for web application post exploitation, and can be used as stealth backdoor or as a web shell to manage legit web accounts, even free hosted ones” (https://tools.kali.org/maintaining-access/weevely). The command syntax is as follows: weevely generate <password> <location to save file to>. Once this command was executed, a success message below the command appeared.

Generate PHP Backdoor Weevly.jpg

The first test for this exploit was done with the DVWA security settings set to low.

Security Settings Low.jpg

I then went back to the Upload page and uploaded the created PHP file generated by weevely.

Upload Shell dot php.jpg

Shell Uploaded Successfully.jpg
Once this file was successfully upload, I opened a terminal back in the attacker system (Kali) and ran the following command: weevely <Target URL to Uploaded File> <password>. The results showed that the connection was made and I was able to successfully run commands on the target server.

Successful Connection.jpg

I decided to see if I could have the same success with increased security settings on DVWA. I set the security settings to medium and tried to repeat the process.

Medium Security Setting.jpg

I tried to upload the PHP file in the same manner and it failed.

Failed PHP Upload Medium.jpg

I decided to use Burp Suite to see if I could manipulate the file type and successfully upload the PHP file. First, I changed the shell.php file to shell.jpg.

Rename to Image File Medium.jpg
I followed by uploading the file to the server with the intercept feature on. Below is the results before the filename was changed in the header using Burp Suite. The following image shows where the filename was modified back to shell.php before forwarding to the server.

Intercept JPG File Type Before Modification Medium.jpg

JPG File Changed to PHP Before Foward Medium.jpg

Once manipulated, I forwarded the request and it was successfully uploaded to the server.

Shell Uploaded Medium.jpg

Following the same methods before to test for connectivity, I was able to successfully send commands to the target server.

Successful Connection Medium.jpg

Lastly, I set the security settings to high to test and see if I would be able to follow the same steps to successfully upload the PHP file as I did with medium settings.
Security Settings High.jpg

My first attempt was not successful. Looking at the source code showed that the settings were checking to ensure that the filename had an image file extension. I decided to manipulate the filename by adding a .jpg to the end. Instead of just changing the filename to shell.php like I did with the medium security settings, I renamed the file shell.php.jpg.

Shell php jpg high.jpg

Once forwarded, the file was successfully uploaded.

Success PHP JPG High.jpg

Going back to weevely, I was able to successfully execute commands on the target machine.

Successful Connection High.jpg

To mitigate against these types of exploitations, first, ensure a user is never permitted to upload executable files (i.e. PHP, EXE, etc.). Additionally, ensure that both the file types AND the file extensions are thoroughly inspected and sanitized for any undesirable types and/or extensions. Lastly, close analysis of the uploaded file itself could prove extremely beneficial. Recreate the file and rename it for closer inspection.

The source code below, called impossible.php, implements these recommendations. It checks to ensure that the file extension is limited to image file file extensions as well as ensures that the image type itself is an image. Also, it uses a PHP library to strip any metadata associated with the user uploaded image, creates a new file with a new file name, ensures that the file extension is of an image file type, and lastly, deletes the user uploaded file from the server. The source code can be seen below and can also be found at https://github.com/ethicalhack3r/DVWA/blob/master/vulnerabilities/upload/source/impossible.php.

<?php

if( isset( $_POST[ 'Upload' ] ) ) {

    // Check Anti-CSRF token

    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];

    // Where are we going to be writing to?

    $target_path   = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';

    //$target_file   = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';

    $target_file   =  md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;

    $temp_file     = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );

    $temp_file    .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;



    // Is it an image?

    if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) &&

        ( $uploaded_size < 100000 ) &&

        ( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&

        getimagesize( $uploaded_tmp ) ) {

        // Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)

        if( $uploaded_type == 'image/jpeg' ) {

            $img = imagecreatefromjpeg( $uploaded_tmp );

            imagejpeg( $img, $temp_file, 100);

        }

        else {

            $img = imagecreatefrompng( $uploaded_tmp );

            imagepng( $img, $temp_file, 9);

        }

        imagedestroy( $img );

        // Can we move the file to the web root from the temp folder?

        if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {

            // Yes!

            $html .= "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>";

        }

        else {

            // No

            $html .= '<pre>Your image was not uploaded.</pre>';

        }

        // Delete any temp files

        if( file_exists( $temp_file ) )

            unlink( $temp_file );

    }

    else {

        // Invalid file

        $html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';

    }

}

// Generate Anti-CSRF token

generateSessionToken();

?>

Comments

Popular posts from this blog

Exploiting Local File Inclusion to Gain Shell Access

Master Port List