DVWA--upload

文件上傳漏洞

0x01瞭解文件上傳漏洞的用處是用來幹什麼的

什麼是文件上傳漏洞?

文件上傳漏洞是指因爲程序員在對用戶文件上傳部分的控制不足或者處理缺陷,而致使的用戶能夠越過其自己權限向服務器上上傳可執行的動態腳本文件。這裏上傳的文件能夠是木馬,病毒,惡意腳本或者WebShell等。這種攻擊方式是最爲直接和有效的,「文件上傳」自己沒有問題,有問題的是文件上傳後,服務器怎麼處理、解釋文件。若是服務器的處理邏輯作的不夠安全,則會致使嚴重的後果。php

文件上傳漏洞自己就是一個危害巨大的漏洞,WebShell更是將這種漏洞的利用無限擴大。大多數的上傳漏洞被利用後攻擊者都會留下WebShell以方便後續進入系統。攻擊者在受影響系統放置或者插入WebShell後,可經過該WebShell更輕鬆,更隱蔽的在服務中隨心所欲。程序員

Webshell簡介

WebShell就是以asp、php、jsp或者cgi等網頁文件形式存在的一種命令執行環境,也能夠將其稱之爲一種網頁後門。攻擊者在入侵了一個網站後,一般會將這些asp或php後門文件與網站服務器web目錄下正常的網頁文件混在一塊兒,而後使用瀏覽器來訪問這些後門,獲得一個命令執行環境,以達到控制網站服務器的目的(能夠上傳下載或者修改文件,操做數據庫,執行任意命令等)。web

WebShell後門隱蔽較性高,能夠輕鬆穿越防火牆,訪問WebShell時不會留下系統日誌,只會在網站的web日誌中留下一些數據提交記錄,沒有經驗的管理員不容易發現入侵痕跡。攻擊者能夠將WebShell隱藏在正常文件中並修改文件時間加強隱蔽性,也能夠採用一些函數對WebShell進行編碼或者拼接以規避檢測。除此以外,經過一句話木馬的小馬來提交功能更強大的大馬能夠更容易經過應用自己的檢測。<?php eval($_POST[a]); ?>就是一個最多見最原始的小馬。shell

0X02low

這個文件上傳的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>";
    }
}

?>

能夠看出 沒有 對任何的文件類型進行過濾 那咱們豈不是隨便上傳一句話木馬?編程

來試試 上傳一下訪問目錄 成功數組

那咱們菜刀鏈接瀏覽器

成功安全

0X02Medium級別的

老規矩咱們先來看一下源碼服務器

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

?> 

能夠看見這裏的函數對咱們的upload的type進行了過濾 只容許

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

這些文件類型才能上傳成功

那咱們嘗試一下繼續上傳一句話木馬 看看能不能成功

 

好像不得行 那咱們嘗試一下一張正常的圖片上傳吶

上傳成功 這是爲何吶 代碼對咱們的文件類型進行了過濾 只有當type=圖片的時候才能上傳成功 那咱們此時怎麼進行繞過吶

咱們來抓包試試 這裏是我上傳木馬的包

 

這裏是我上傳圖片的包

 看咱們的源碼能夠知道 這裏是對咱們的type進行了過濾的 那麼咱們修改一下這個看看是否能上傳成功吶 咱們把圖片上傳成功的type粘貼過來 

上傳成功

0X04high

這裏先對一些函數名稱作一些介紹

PHP strtolower() 函數
把全部字符轉換爲小寫:
<?php
echo strtolower("Hello WORLD.");
?>
 PHP編程語言中的常見的$_FILES系統函數用法有:
$_FILES['myFile']['name'] 顯示客戶端文件的原名稱。
$_FILES['myFile']['type'] 文件的 MIME 類型,例如"image/gif"。
$_FILES['myFile']['size'] 已上傳文件的大小,單位爲字節。
$_FILES['myFile']['tmp_name'] 儲存的臨時文件名,通常是系統默認。
$_FILES['myFile']['error'] 該文件上傳相關的錯誤代碼。如下爲不一樣代碼表明的意思:
HP 獲取圖像信息 getimagesize 函數

    getimagesize() 函數用於獲取圖像尺寸,類型等信息。
    imagesx() 函數用於獲取圖像的寬度。
    imagesy() 函數用於獲取圖像的高度。

getimagesize()

getimagesize() 函數用於獲取圖像大小及相關信息,成功返回一個數組,失敗則返回 FALSE 併產生一條 E_WARNING 級的錯誤信息。

語法:

array getimagesize( string filename )

例子:

<?php
$array = getimagesize("images/flower_1.jpg");
print_r($array);
?>

瀏覽器顯示以下:

Array
(
    [0] => 350
    [1] => 318
    [2] => 2
    [3] => width="350" height="318"
    [bits] => 8
    [channels] => 3
    [mime] => image/jpeg
)

 

這個級別的咱們也來看一下源碼 這是個什麼東西

 <?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);
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) { 

那麼這些代碼是什麼意思吶?

在這條語句裏,首先利用strrpos() 函數來查找「.」在變量$uploaded_name中出現的位置,而後將獲得的數值加1,最後利用substr()函數從變量$uploaded_name的指定位置截取部分字符串。

總之,這條語句的做用就是從咱們所上傳的文件名中截取出擴展名部分。

清晰明瞭

接下來就用if語句來判斷這個擴展名是不是大寫或小寫的jpg/jpeg,若是不是的話則不容許上傳,於是這裏就是定義了一份白名單,這也是安全性比較高的一種防護措施。

這裏你覺得你直接把馬的後綴改爲JPG上傳會失敗

 

 這裏由於getimagessize(繞過方法是00截斷)函數對文件的開頭內容進行了檢測  經過二進制識別你是否爲圖像 這裏咱們直接加上GIF89a就能夠成功繞過

 

而後上傳

這裏由於是上傳的jpg圖像因此菜刀不能直接鏈接 咱們用咱們的文件包含漏洞來執行菜刀鏈接

http://127.0.0.1/dwva/vulnerabilities/fi/?page=file:///C:\phpStudy1\PHPTutorial\WWW\dwva\hackable\uploads\1234.jpg

可是這裏咱們用文件包含能訪問 可是不能執行

那咱們嘗試一下copy的方法

http://127.0.0.1/dwva/vulnerabilities/fi/?page=file:///C:\phpStudy1\PHPTutorial\WWW\dwva\hackable\uploads\3.jpg

用文件包含漏洞去執行

而後菜刀鏈接

成功了

這裏文件包含的時候必定要注意 反斜槓 \ 和/別打反了 我以前就一直打反了 一下午沒鏈接上 

本站公眾號
   歡迎關注本站公眾號,獲取更多信息