thinkphp反序列化漏洞审计应聚焦三类高危入口:phar://等伪协议触发点、用户可控文件路径拼接处(如include/fopen)、第三方组件中含__destruct等魔术方法的类(如psr6cache);关键在追踪参数是否未经校验即进入危险函数,而非仅搜索unserialize。

直接上手审计 ThinkPHP 项目,别从“学框架原理”开始——先盯住三类高危入口点,再反向查调用链,效率最高。
怎么快速定位 unserialize 入口点
ThinkPHP 5.x/6.x 的反序列化漏洞大多不是因为开发者写了 unserialize($_GET['data']) 这种显眼代码,而是藏在组件调用或缓存逻辑里。真正该搜的不是函数名,是“能触发反序列化的上下文”:
- 全局搜索
phar://、phar.、.phar字符串,尤其关注file_exists、is_file、fopen、getimagesize等函数的参数来源 - 检查所有接收用户文件路径的地方(如附件预览、模板加载、日志下载),看是否未经校验就拼接进
file_get_contents()或include() - ThinkPHP 6.0.13 的 CVE-2022-38352 就是通过
League\Flysystem\Cached\Storage\Psr6Cache的__destruct触发的,所以得顺藤摸瓜找第三方组件中含魔术方法的类
目录遍历漏洞最常出在哪几个参数上
TP3.2.3 和 TP5.x 中,$_GET['file']、$_GET['tpl']、$_COOKIE['template']、$_POST['filename'] 是高频雷区,但关键不在参数名,而在后续是否做 realpath() + 根目录白名单校验:
- 只要看到
include(APP_PATH . $_GET['file'])或fopen(DATA_PATH . $_POST['filename'])这类拼接,基本就是漏洞候选 - 注意 URL 编码绕过:
%2e%2e%2f、%c0%ae%c0%ae%2f在 TP3.x 默认不自动解码,pathinfo()提取后缀前必须先urldecode() - TP5.x 的
think\view\driver\Think类中fetch()方法若接受用户传入的$template,且未限制路径范围,也会被用于遍历
为什么 RIPS 扫出来一堆“高危”却没法利用
RIPS 报告里的 eval()、assert()、call_user_func() 告警,90% 都是误报——它只认数据流,不认业务逻辑:
- 如果
eval()的参数来自配置文件或硬编码字符串(如eval('return 1;')),RIPS 仍会标红,但实际无风险 - ThinkPHP 的
think\route\Url::__toString()在 6.x 某些版本中会触发call_user_func,但前提是对象属性被可控赋值,RIPS 不会自动判断赋值是否可达 - 真正要人工确认的是:变量从
$_GET开始,是否经过任何过滤函数(如htmlspecialchars、intval、filter_var)?中间有没有被重赋值或类型转换?
复杂点在于:TP6 的容器注入、TP5 的路由参数解析、TP3 的模板加载,三者触发 RCE 的路径完全不同,不能套同一套审计流程;最容易被忽略的是——很多“已修复”项目只是升级了框架版本,但遗留的自定义插件或中间件仍沿用旧版危险写法。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











