米斯特白帽培訓(xùn)講義 漏洞篇 文件包含
講師:gh0stkey
整理:飛龍
協(xié)議:CC BY-NC-SA 4.0
原理
文件包含就是將一個(gè)文件包含到自己的文件中執(zhí)行泥从。它可分為本地包含和遠(yuǎn)程包含牍颈,本地包含即包含本地磁盤上的文件野舶,文件名稱是相對(duì)路徑或絕對(duì)路徑灶壶,遠(yuǎn)程包含即包含互聯(lián)網(wǎng)上的文件钓瞭,文件名稱是 URL姆蘸。
本地包含
比如我們有一個(gè)test.txt
文件祝蝠,僅僅調(diào)用phpinfo
來測(cè)試:
<?php phpinfo();?>
然后我們?cè)谙嗤夸浵路胖靡粋€(gè)fileinclude.php
,如下:
<?php
$file=@$_GET['file'];
if($file){
echo "<center>File:".$file."<br/>Result:</center>";
include $file;
}
第一行代碼獲取 URL 參數(shù)file
的內(nèi)容绣张。2 ~ 4 行首先判斷$file
是否為空答渔,若不為空,輸出其內(nèi)容侥涵,并將其作為文件名稱包含沼撕。
我們將其部署在localhost
下宋雏,之后訪問http://localhost/fileinclude.php?file=test.txt
,會(huì)看到phpinfo
的輸出务豺。
我這里之所以用txt
文件磨总,就是想說明這個(gè)漏洞是無視擴(kuò)展名的。跟文件上傳漏洞不一樣笼沥,文件上傳漏洞中如果我們上傳的文件不是.php
就執(zhí)行不了(當(dāng)然也有一些繞過手段)蚪燕,但是文件包含漏洞中的擴(kuò)展名是任意的,這里我們上傳了.txt
奔浅,證實(shí)有效馆纳,那么這個(gè).jpg
也是有效的。
要注意汹桦,如果被包含的文件里面沒有 PHP 標(biāo)簽鲁驶,那么就當(dāng)成 HTML 內(nèi)容如實(shí)顯示出來。就比如我們放入之前的top100.txt
:
遠(yuǎn)程包含
為了演示遠(yuǎn)程包含舞骆,我們需要將 PHP 配置文件中的allow_url_include
設(shè)置為on
钥弯,之后重啟 PHP。PHP 配置文件的位置可以在phpinfo
的輸出中尋找葛作,我們搜索ini
即可:
我這里是C:\php-5.5.10\php.ini
寿羞,你那里可能有些差別。我們打開它赂蠢,搜索allow_url_include
绪穆,會(huì)看到下面這些行,如果是Off
把它改成On
虱岂。
; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-include
allow_url_include = On
我們需要將file
參數(shù)改為http://localhost/text.txt
玖院,可以看到相同結(jié)果。
技巧
00 截?cái)?/h3>
有些程序會(huì)給被包含內(nèi)容加一些后綴第岖,比如如果fileinclude.php
是這樣难菌。
<?php
$file=@$_GET['file'];
if($file){
$file .= '.php';
echo "<center>File:".$file."<br/>Result:</center>";
include $file;
}
它后面加了個(gè).php
,也就是說蔑滓,如果我們傳入file=test
則是正常的郊酒,傳入file=test.txt
,或變成test.txt.php
键袱,從而包含失敗燎窘。那么我們應(yīng)該怎么辦呢?
如果 PHP 版本小于 5.3蹄咖,并且magic_quotes_gpc
已取消褐健,我們就可以使用%00
來截?cái)唷N覀儌魅?code>file=test.txt%00澜汤,就可以實(shí)現(xiàn)包含蚜迅。
路徑遍歷
-
./
(或省略):當(dāng)前目錄 -
../
:上級(jí)目錄 -
/
:根目錄(Windows 中為當(dāng)前盤內(nèi)的根目錄) -
~/
:用戶的主目錄
例如舵匾,在 Linux 下,我們就可以使用file=/etc/passwd
來讀取系統(tǒng)密碼谁不。
這里是一些常見的日志文件位置:
- apache+Linux日志默認(rèn)路徑
/etc/httpd/logs/access.log
/var/log/httpd/access.log
- apache+win2003日志默認(rèn)路徑
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
- IIS6.0+win2003默認(rèn)日志文件
C:\WINDOWS\system32\Lognames
- IIS7.0+win2003 默認(rèn)日志文件
%SystemDrive%\inetpub\logs\Lognames
- nginx 日志文件
<安裝目錄>/logs
- 如果安裝目錄為
/usr/local/nginx
坐梯,則為/usr/local/nginx/logs
- apache+linux 默認(rèn)配置文件
/etc/httpd/conf/httpd.conf
/etc/init.d/httpd
- IIS6.0+win2003 配置文件
C:/Windows/system32/inetsrv/metabase.xml
- IIS7.0+WIN 配置文件
C:\Windows\System32\inetsrv\config\applicationHost.config
PHP 偽協(xié)議
允許遠(yuǎn)程包含的情況下,我們可以使用php://
偽協(xié)議刹帕,比如php://filter/resource=test.txt
可以讀取相同文件烛缔。
我們還可以加一個(gè)過濾器讓它顯示為 BASE64 編碼格式,php://filter/read=convert.base64-encode/resource=test.txt
轩拨。如果我們要獲取的文件里面有不可打印的字符,或者我們想要獲取代碼的內(nèi)容院喜,可以用這種方式來獲取亡蓉,之后解碼即可。
php://input
可以讀取原始的 HTTP 正文內(nèi)容喷舀。如果我們將file
設(shè)置為php://input
砍濒,并且在 HTTP 正文中傳入 PHP 代碼,例如<?php phpinfo();?>
硫麻,即可執(zhí)行代碼爸邢。
Data URI
Data URI 的格式是data://text/plain;base64,<base64>
,同樣需要遠(yuǎn)程包含拿愧。我們首先把一句話用 base64 編碼杠河,得到PD9waHAgcGhwaW5mbygpOz8+
,然后將file
設(shè)置為data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
(注意URL編碼)浇辜,即可執(zhí)行代碼券敌。
如何挖掘
首先對(duì) URL 進(jìn)行分析,看看是否和文件相關(guān)柳洋,比如www.test.com/xxx.php?file=yyy
待诅。帶有文件相關(guān)的敏感名稱都可以進(jìn)行挖掘。
利用
當(dāng)我們發(fā)現(xiàn)了本地包含漏洞時(shí)熊镣,首先尋找上傳點(diǎn)卑雁,比如用戶頭像上傳功能。然后我們可以構(gòu)造一個(gè)純文本文件绪囱,內(nèi)容為<?php phpinfo();?>
测蹲,并將其命名為xxx.jpg
。
之后我們就可以把xxx.jpg
上傳上去毕箍,并通過應(yīng)用得到它的位置弛房,假設(shè)是/upload/xxx.jpg
,然后我們就可以把file
參數(shù)的值改為它而柑。以前面的代碼為例文捶,URL 是http://localhost/fileinclude.php?file=/upload/xxx.jpg
荷逞。
如果我們把xxx.jpg
的內(nèi)容改為菜刀的一句話,那就可以用菜刀連接粹排。
再說一下遠(yuǎn)程包含种远,遠(yuǎn)程包含的條件比較苛刻,目標(biāo)網(wǎng)站需要把allow_url_open
給打開顽耳。所以有本地包含不一定有遠(yuǎn)程包含坠敷,有遠(yuǎn)程包含一定就有本地包含。但是射富,遠(yuǎn)程包含的利用相對(duì)簡單膝迎,只要將代碼上傳到自己博客,或者任何能通過 URL 訪問到的地方就可以了胰耗。后續(xù)步驟是一樣的限次。