PHP反序列化可通过__wakeup()或__destruct()等魔术方法调用file_get_contents()、curl_exec()等函数,若参数来自未过滤的反序列化数据,即可触发SSRF;典型利用链为反序列化→魔术方法执行→可控URL发起内网请求→探测Redis、读取元数据或写Webshell;防御需协同禁用危险函数加载、白名单校验URL并禁止内网IP。

PHP反序列化如何成为SSRF的“引信”
反序列化本身不直接发起网络请求,但它能控制对象生命周期中的魔术方法执行时机。当__wakeup()或__destruct()里调用了file_get_contents()、curl_exec()等函数,且参数来自未过滤的反序列化数据时,就形成了“反序列化 → 触发SSRF”的利用链。
典型场景如:后台接收用户提交的序列化字符串用于日志记录或缓存重建,反序列后在__destruct()中尝试向某个配置URL发起健康检查请求——这个URL若可被攻击者注入,就完成了从反序列化到SSRF的跃迁。
构造可控的SSRF触发点
关键在于让反序列化后的对象,在魔术方法中拼接出攻击者指定的目标地址。常见手法包括:
- 定义类属性为URL模板(如
$this->target = 'http://127.0.0.1:6379'),在__destruct()中直接传入file_get_contents($this->target) - 利用
__toString()返回恶意URL字符串,再被其他函数(如echo $obj)隐式触发请求 - 配合
unserialize()前的输入点(如日志ID、session值、回调参数),将payload嵌入合法业务流中,绕过简单WAF检测
从SSRF走向内网渗透的实操路径
一旦SSRF通道打通,重点转向协议选择与目标服务识别:
立即学习“PHP免费学习笔记(深入)”;
-
探测内网存活主机:用
http://172.18.0.2/、http://192.168.1.100/等常见网段批量测试HTTP响应;也可用gopher://172.18.0.2:6379/_*1%0D%0A$4%0D%0AINFO%0D%0A直连Redis判断服务状态 -
打未授权Redis写Webshell:构造gopher协议payload,通过SSRF发送
CONFIG SET dir /var/www/html/和CONFIG SET dbfilename shell.php,再SET含<?php @eval($_POST[cmd]);?>的内容并SAVE -
访问云元数据接口:对阿里云、AWS等环境,尝试
http://100.100.100.200/latest/meta-data/获取临时AK、实例信息等高价值凭证
防御要堵住两个关键缺口
单防反序列化或单防SSRF都不够,必须协同加固:
- 禁用危险函数的自动加载机制,如在
php.ini中设置unserialize_callback_func = "",并移除__wakeup/__destruct中所有网络操作逻辑 - 对所有用户可控的URL参数做白名单校验:只允许
http/https协议、限定域名后缀(如.example.com)、禁止内网IP段(127.0.0.0/8、192.168.0.0/16等) - 使用
parse_url()二次解析URL,比对host字段是否为纯域名(不含IP),并拒绝302跳转和DNS重绑定类绕过



















