PHP 偽協議(PHP Stream Wrapper)
PHP 的偽協議(Protocol Wrapper)是一種機制,允許開發者通過統一的文件訪問函數(如 file_get_contents
、fopen
、include
等)訪問不同類型的數據源,包括本地文件、遠程資源、內存數據、壓縮包等。
原理說明
PHP 偽協議本質上是對路徑的一種特殊格式擴展,它將以特定協議開頭的路徑重定向到不同的數據處理器。例如:
file_get_contents("php://input");
上述代碼讀取的不是文件,而是 HTTP 請求體的原始內容。
常見偽協議分類及功能
偽協議 | 功能說明 |
---|---|
file:// | 默認本地文件訪問,可省略 file:// 前綴 |
php://filter | 對文件內容進行過濾,如編碼轉換(如 base64) |
php://input | 讀取原始 POST 請求體數據 |
php://memory / php://temp | 使用內存/臨時文件作為讀寫流 |
data:// | 讀取內聯數據,適用于直接包含字符串內容 |
zip:// | 訪問 zip 壓縮包中的文件 |
phar:// | 訪問 Phar 存檔文件內容 |
glob:// | 使用通配符進行文件匹配 |
http:// / https:// | 遠程網頁數據讀取(依賴 allow_url_fopen ) |
ftp:// | 讀取遠程 FTP 文件 |
expect:// | 執行 shell 命令(高危,默認禁用) |
常見利用場景及用法
1. php://filter
讀取源碼(常用于 CTF)
讀取 PHP 文件并進行 base64 編碼:
file_get_contents("php://filter/convert.base64-encode/resource=index.php");
可用于源碼查看或繞過 Web 服務對 .php
文件的訪問限制。
2. php://input
讀取原始 POST 數據
$raw = file_get_contents("php://input");
適用于接收非標準 Content-Type
的 POST 數據,比如上傳 Webshell 繞過限制。
3. data://
內聯數據作為代碼包含
include("data://text/plain,<?php phpinfo(); ?>");
可以直接把一段字符串當作 PHP 文件執行,常用于代碼注入場景。
4. zip://
讀取壓縮包內的文件
file_get_contents("zip://shell.zip#shell.php");
配合文件上傳漏洞使用,將 PHP 文件嵌入 zip 包中,繞過后綴檢測。
5. phar://
配合反序列化漏洞使用
include("phar://shell.jpg");
Phar 文件在被解析時會自動觸發反序列化邏輯,可用于 POP 鏈觸發。
安全風險
PHP 偽協議可被濫用,尤其是在存在以下漏洞時:
-
本地文件包含(LFI)
-
遠程文件包含(RFI)
-
反序列化(Phar 利用)
-
文件上傳(zip 包繞過)
-
任意文件讀取(結合 filter)
攻擊者可以利用偽協議讀取敏感信息、執行任意代碼、泄露源碼等。
示例:利用 LFI + php://filter 獲取源碼
<?php
include($_GET['file']);
訪問:
?file=php://filter/convert.base64-encode/resource=flag.php
結果為 flag.php
文件的 base64 編碼內容。
總結表
類型 | 示例 | 功能說明 |
---|---|---|
本地文件 | file://index.php | 常規文件讀寫 |
網絡訪問 | http://example.com | 獲取遠程網頁數據 |
輸入流 | php://input | 獲取原始 POST 數據 |
編碼過濾 | php://filter/convert.base64-encode/resource=index.php | 獲取源碼并 base64 編碼輸出 |
內聯數據 | data://text/plain,<?php phpinfo(); ?> | 執行/包含內嵌內容 |
壓縮包 | zip://shell.zip#shell.php | 訪問 zip 包中的 PHP 文件 |
Phar 文件 | phar://shell.jpg | 使用 Phar 進行反序列化利用 |