DVWA靶場通關----(5) File Upload教程


File Upload(文件上傳)

File Upload(文件上傳),由於對上傳文件的內、類型沒有做嚴格的過濾、檢查,使得攻擊者可以通過上傳木馬文件獲取服務器的webshell文件。

File Upload主題:

 

Low

源碼解析

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
//文件的目標路徑hackable/uploads/,也就是文件上傳的位置
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
// basename(path,suffix)

//函數返回路徑中的文件名部分,如果可選參數suffix為空,則返回的文件名包含后綴名,反之不包含后綴名。
    $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>";
    }
}

?>

漏洞復現

  從源碼中可以看到對上傳文件的類型、內容沒有做任何的過濾與檢查,同時告訴了我們文件上傳的路徑,存在明顯的文件上傳漏洞。

(1)上傳一個phpinfo.php進行測試

 當我們上傳成功后,會提示我們成功上傳,並且返回一個上傳文件的路徑

(2)打開我們所上傳的文件

 

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?
//文件類型必須是image/jpeg 或者 image/png,大小不能超過100000B(約為97.6KB)
    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>';
    }
}

?>

  對文件上傳的類型做了限制,要求必須是image/jpeg 或者 image/png 類型的。

漏洞復現

(1)還是使用剛才的phpinfo.php(把剛才上傳的那個記得刪掉)

 

 (2)打開上傳的文件

 

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?
// strtoLower把所有字符轉換為小寫
getimagesize(string filename)
函數會通過讀取文件頭,返回圖片的長、寬等信息,如果沒有相關的圖片文件頭,函數會報錯。
可以看到,High級別的代碼讀取文件名中最后一個”.”后的字符串,期望通過文件名來限制文件類型,因此要求上傳文件名形式必須是”*.jpg”、”*.jpeg” 、”*.png”之一。同時,getimagesize函數更是限制了上傳文件的文件頭必須為圖像類型。
    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>';
    }
}

?>

  這個就必須上傳一個圖片馬了,他對文件的文件頭,文件名形式等等都做了檢查。

漏洞復現

(1)先制作一個圖片馬(注意:圖片馬的文件大小不能超過100000B)

copy phpinfo.png/b+phpinfo.php/a phpinfo.png

 

 (2)將准備好的圖片馬上傳

 (3)打開上傳的圖片馬,可以看到上傳成功

 (4)結合文件包含漏洞,去包含我們上傳的文件,成功執行phpinfo

 

Impossible

源碼解析

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

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

    // Where are we going to be writing to?
    $target_path   = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
    //$target_file   = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
//上傳文件的文件前綴md5加密
    $target_file   =  md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
//in_get(varname)
函數返回相應選項的值
    $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' ) {
//imagecreatefromjpeg ( filename )
函數返回圖片文件的圖像標識,失敗返回false
            $img = imagecreatefromjpeg( $uploaded_tmp );
//imagejpeg ( image , filename , quality)
從image圖像以filename為文件名創建一個JPEG圖像,可選參數quality,范圍從0(最差質量,文件更小)到100(最佳質量,文件最大)。
            imagejpeg( $img, $temp_file, 100);
        }
        else {
            $img = imagecreatefrompng( $uploaded_tmp );
            imagepng( $img, $temp_file, 9);
        }
// imagedestroy( img )
函數銷毀圖像資源
        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!
            echo "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>";
        }
        else {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }

        // Delete any temp files
        if( file_exists( $temp_file ) )
            unlink( $temp_file );
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

漏洞復現

  這個級別的文件上傳對上傳的文件進行了重命名(搞了一個MD5的加密),還增加了token值的校驗,對文件的內容也做了嚴格的檢查。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM