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 进行反序列化利用 |