1. 程式人生 > >DVWA & File Upload檔案上傳最詳細繞過

DVWA & File Upload檔案上傳最詳細繞過

DVWA的使用練習:

今天學習的內容很有意思,也很實用。
DVWA其實本質上就是一個脆弱系統,它需要的是php+mysql的環境,旨在為安全人員提供一個合法的環境用來測試自己的專業技能和工具,並且讓web安全工作著深刻的理解漏洞防範和入侵的本質原理,很適合我們這種小白鍛鍊自己,好廢話不多說。。。。。

首先DVWA環境安裝:
在下載DVWA之前我們需要一個php+mysql的環境,apache+php+mysql的環境搭建就不過多贅述了,百度帖子就很多,同時這一套環境作為一個安全工作者來說也是必備的,我的環境在虛擬機器裡,懶到不行。。就直接用了phpstudy做了環境。
去http://www.dvwa.co.uk/下載dvwa的壓縮包,將其解壓到phpstudy中www資料夾下
這裡寫圖片描述

然後去config檔案下有一個config.inc.php.dist檔案,將其後面的.dist刪除,形成config.inc.php檔案,之後開啟更改你資料庫的使用者名稱和密碼。
這裡寫圖片描述
這裡寫圖片描述
圖中的地方預設賬號密碼都是root,更改為你自己MySQL的使用者名稱和密碼,之後執行127.0.0.1/DVWA/setup.php就出現了頁面,
這裡寫圖片描述
下面有一個Creat/Reset Datebase 點選後它就自動建立好了資料庫,然後登陸,預設賬號密碼root/password。
以上環境就完全搭建好了,簡單。
之後進行實踐操作,今天我進行的是file upload 的實踐,在這裡說一下dvwa環境包含了十個常用模組:
1.Brute Force(暴力(破解))
2.Command Injection(命令列注入)
3.CSRF(跨站請求偽造)
4.File Inclusion(檔案包含)
5.File Upload(檔案上傳)
6.Insecure CAPTCHA (不安全的驗證碼)
7.SQL Injection(SQL注入)
8.SQL Injection(Blind)(SQL盲注)
9.XSS(Reflected)(反射型跨站指令碼)
10.XSS(Stored)(儲存型跨站指令碼)
同時平臺設定了四個難度的等級,low,medium,high,impossible.同時你可以看他們的原始碼,對於你的程式碼審計能力有很大的幫助,每一個等級的過濾機制,實現過程一目瞭然。
就拿upload(檔案上傳)來說,每一等級的過濾就很不一樣。
首先我們來看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>";
    }
}

?> 

這段程式碼的核心就是驗證是否有接收檔案**($_POST[‘Upload’])然後組合檔案根路徑成為*target_path***就是目標路徑。

$target_path = DVWA_WEB_PAGE_TO_ROOT.“hackable/uploads/”;

DVWA_WEB_PAGE_TO_ROOT=D:\phpstudy\WWW\DVWA
$target_path=D:\phpstudy\WWW\DVWA/hackable/uploads/

target_path = target_path . basename($_FILES[‘uploaded’][‘name’]);

因此最終你上傳的檔案的最終路徑為:
$target_path=D:\phpstudy\WWW\DVWA/hackable/uploads/123.jpg

123.jpg就是你要上傳的目標檔案。
之後我們看到它對上傳的檔案沒有任何的要求,檔案型別或是檔案大小都沒有做規定,於是我們可以輕鬆的傳我們的木馬上去,這也果然是低等級的啊。

然後我們再看中等級:


File Upload Source
<?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>';
    }
}

?>



我們看到中等級就相對嚴密了很多,它對檔案的型別和大小做了明確的限制。

( uploaded_type == “image/jpeg” || uploaded_type == “image/png” ) &&
( $uploaded_size < 100000 )

限定了格式為image/jpeg或是png 大小小於100000位元組的檔案才能上傳,而這個問題我們抓包就可以解決。
開啟burpsuit, 我們攔一下上傳包,改一下他的上傳格式,繞過攔截。
這裡寫圖片描述
這裡寫圖片描述

然後我們發現上傳成功,原始檔裡也確實上傳成功了。
這裡寫圖片描述

這種看似很規範的攔截其實也形同虛設,我們上傳的木馬等大小一般不會超過100000位元組,而對檔案型別的檢查也僅僅看上傳檔案的提交屬性,所以十分有機可乘。如果他能對檔案頭或者檔名驗證更明確才會有些難度。

所以我們來看一下高階的難度,看看嘗試可不可以繞過上傳。

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

?> 

我們看到高階難度的驗證就更嚴格了,它多了一句這個:

(($uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, ‘.’
) + 1);

他的作用是什麼呢?
其實他是防範iis 6.0檔案解析漏洞的,有時我們為了繞過限制會提交這樣形式的檔案:
Xx.asp;.xx.jpg xx.jpg
而這句話的作用就是說它會驗證檔案的最後一個點之後的格式上面的例子來說就是不管你前面寫了多少,我只驗證最後的 ’.jpg’。

strtolower( $uploaded_ext ) == “jpg” || strtolower( $uploaded_ext ) ==“jpeg” || strtolower( $uploaded_ext ) == “png”

同時這句話對上傳檔案的型別做了更明確的要求,只識別jpg 和 jpeg 的檔案,這個就有些難度了,而我們只能嘗試一下%00截斷了。

%00在url語言裡代表空格“ ”,因此它起到的作用就是截斷檔案的後半段,讓它識別到的檔案格式是.jpg,而解析時會是前面的指令碼格式。我們試一下。

這裡寫圖片描述
我上傳了一個hedan.php.jpg檔案然後進行%00截斷。

這裡寫圖片描述
這裡寫圖片描述

仔細檢視後發現%00截斷需要PHP<5.3.4,實驗環境為5.6.35所以無法利用。
所以只能換別的方法了;

我做了一張圖片隱藏後門fun.jpg
這裡寫圖片描述
用16進位制編輯器010editor實現,檔案上傳。

這裡寫圖片描述
上傳後可以正常訪問,而此時我們的難題就是怎麼讓檔案被解析而觸發我們的後門

這裡寫圖片描述
發現檔案被解析,下面我們菜刀連線就好了。