站在巨人的肩頭才會看見更遠的世界,這是一篇技術牛人對CTF比賽中文件包含的內容總結,主要是對一些包含點的原理和特征進行歸納分析,並結合實際的例子來講解如何繞過,全面細致,通俗易懂,掌握這個新技能定會讓你在CTF路上少走很多彎路,不看真的會后悔!

php偽協議的分類
偽協議是文件包含的基礎,理解偽協議的原理才能更好的利用文件包含漏洞。
php://input
php://input代表可以訪問請求的原始數據,簡單來說POST請求的情況下,php://input可以獲取到post的數據。
使用條件:include( )、include_once( )、file_get_contents( )
比較特殊的一點,enctype=”multipart/form-data”的時候 php://input 是無效的。
用法舉例:
- 使用file_get_contents函數的偽協議包含有個經典的例子;
- 可以使用fputs文件輸入流直接服務器某一存在的目錄下寫入文件。
php://output
php://output 是一個只寫的數據流,允許你以print和echo一樣的方式寫入到輸出緩沖區。
php://filter(重點)
php://filter是一種元封裝器,設計用於數據流打開時的篩選過濾應用,也就是作為一種過濾器,可以使用在數據流產生的地方。

在php文檔中,標准的定義是這樣的:
類似的過濾器還有string.rot13、string.strip_tags、zlib.deflate和zlib.inflate等等,目前只要知道convert.base64-encode就好了。
URL 中包含點的常見形式
?file = xxx 或者 ?file = xxx.php

allow_url_fopen和allow_url_include
在測試了包含點存在包含漏洞以后,並不是都可以使用filter偽協議包含出源碼的,因為allow_url_fopen和allow_url_include會影響到fopen和include等函數對於偽協議的支持。
allow_url_include影響php://input的使用,若不打開則無法使用。
當allow_url_fopen打開時,可以包含任意url。
例如只打開allow_url_include時,只能包含遠程文件和使用php://input
舉個例子
題目鏈接:http://level3.tasteless.eu/
題目直接給出了源碼:
根據提示,用php://input 偽協議讀取php.ini

找到SERVER["DOCUMENT_ROOT"],也就是網站的根目錄,可以找到當前腳本的目錄,如下:
還可以看到一些文件包含的配置:
- rfi是關閉的,也就是allow_url_fopen為Off;
- allow_url_include開啟,可以使用php://input偽協議來列出當前目錄下的文件。
payload:

繞過 waf 的方法
字典繞過
在一些CTF中會對一些偽協議的關鍵詞進行過濾,如read、resource等等,下面總結了幾條繞過方法,在實戰中作為字典來跑。
?f=php://filter/convert.base64-encode/resource=login.php(過濾了操作名read)
?f=php://filter/read=convert.base64-encode/resource=1.jpg/resource=./show.php(正則 /resource=*.jpg/i)
?f=data:text/plain,<?php phpinfo()?>
?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
這里說一下第二條,這是2018 ISCC中的一道題目的繞過方法。
這里用正則匹配了resource=,我們就可以用重寫的方法來繞過正則。
截斷包含
截斷
這里技巧現在應該是用的比較少了,因為利用截斷要滿足下面的兩個條件:
- php版本小於5.3.4
- magic_quotes_gpc為off
./ 截斷
點號和路徑截斷以及./截斷,也就是填充大量的./使url長度超過最大值,來達到截斷的目的。
具體可以看下面的文章:
https://blog.csdn.net/zvall/article/details/8951925
zip協議和phar協議
在實戰過程中,若發現存在文件上傳但是沒有辦法直接上傳php文件,可以傳zip壓縮文件,我們就利用這兩個協議,將php文件打包成zip文件來包含里面的php腳本。
phar://、zip://,都可以看到在phpinfo中有相應的描述。
例如腳本文件為1.php,打包成1.zip,然后再改名為1.jpg,上傳之后包含1.jpg中的php文件即可。
zip://..(當前腳本的絕對路徑).../1.jpg#1.php
phar://...(當前腳本的絕對路徑).../1.jpg/1(分割不加后綴名)