PHP 7.2.34虽未列入CVE-2026-109618/109619修复列表,但因缺乏unserialize白名单机制且__wakeup/__destruct等魔术方法处理逻辑未加固,仍存在高风险反序列化漏洞,可利用现成POP链(如FileRead::__destruct读文件)或常见gadget(SimpleXMLElement、SplFileObject等)实现RCE或敏感信息泄露。

PHP 7.2.34 属于 已知存在反序列化风险的旧版本,虽不在最新 CVE-2026-109618/109619 的直接修复列表(该漏洞影响至 8.5.12),但其本身对 __wakeup、__destruct 等魔术方法的处理逻辑未做现代加固,且缺乏对 unserialize() 输入的默认白名单机制,POP 链构造仍高度可行,关键在于目标环境中可用的类与函数。
以下为实用、可落地的构造思路,聚焦真实环境常见路径:
明确 POP 链触发入口点
POP 链本质是“可控对象 → 魔术方法 → 敏感操作”的链式调用。必须先确认:
- 应用是否接收并反序列化用户输入(如
unserialize($_GET['data'])、unserialize(file_get_contents('cache.bin'))) - 是否存在可利用的类(尤其含
__wakeup/__destruct/__toString的类) - 是否禁用危险函数(如
system、exec、file_get_contents)——若禁用,需转向file_put_contents、include、assert或call_user_func等替代路径
⚠️ 注意:PHP 7.2.34 中
__wakeup在反序列化时一定执行(除非类定义了__wakeup且 PHP立即学习“PHP免费学习笔记(深入)”;
检查常见可利用类与 gadget
不必从零写类,优先搜索目标源码或已知组件中的“现成 gadget”:
-
SimpleXMLElement+__toString:配合外部实体(XXE)读取本地文件(需libxml启用) -
Exception/Error子类:若重写了__toString并拼接$this->message,可触发echo $obj场景下的任意字符串输出 -
SplFileObject/DirectoryIterator:__toString可能触发文件读取或目录遍历 -
自定义类中的
__destruct调用file_get_contents($this->filename):最典型链,只需控制$filename即可读取任意文件(如/etc/passwd或flag.php)
示例链(简化):
class FileRead {
private $filename = '/etc/passwd';
public function __destruct() {
echo file_get_contents($this->filename);
}
}
echo urlencode(serialize(new FileRead()));绕过常见过滤手段(实战高频)
很多题目或 CMS 会加正则过滤(如 preg_match('/[a-z]+Class/i', $input))、关键词黑名单(system|exec|flag)或类型校验:
-
大小写/编码混淆:
SyStEm、base64_decode('c3lzdGVt')、create_function('', 'system($_GET[1]);')(注意:create_function在 7.2 已弃用但仍可用) -
动态函数调用:用
$func = 'file'.'get_'.'contents'; $func('/flag');绕过静态扫描 -
数组键名/属性名混淆:若反序列化前有
json_decode(..., true)再转对象,可尝试O:4:"Test":1:{s:8:"filename";s:8:"/flag";}配合类中public $filename -
利用
__toString触发二次调用:例如某类A的__toString返回$this->obj->data,而$this->obj是可控的B类实例,B::__toString又调用file_get_contents—— 形成二级链
快速验证与调试建议
- 本地搭 PHP 7.2.34 环境(Docker 镜像
php:7.2.34-apache可用),复现目标类逻辑 - 使用
var_dump()或error_log()在每个魔术方法中打点,确认链是否走到预期位置 - 若
unserialize()报错Notice: unserialize(): Error at offset,检查:- 字符串是否被 URL 解码/HTML 实体转义破坏
- 类名大小写是否与实际定义一致(PHP 7.2 区分大小写)
- 私有属性格式是否正确(
%00ClassName%00property)
不复杂但容易忽略。



















