ThinkPHP6.0 任意文件操作
字数 938 2025-08-26 22:11:56
ThinkPHP6.0 任意文件操作漏洞分析与复现
漏洞概述
ThinkPHP6.0 中存在一个任意文件操作漏洞,攻击者可以通过精心构造的Session ID来在服务器上创建或覆盖任意文件。该漏洞源于Session ID验证不足,导致攻击者可以控制文件路径和内容。
漏洞分析
漏洞原理
- Session ID验证不足:ThinkPHP6.0 在设置Session ID时仅检查长度是否为32,未对字符类型进行严格验证
- 文件路径构造:Session数据会被存储在文件中,文件名由
sess_前缀加上Session ID构成 - 目录遍历:攻击者可以通过构造包含路径遍历字符(
../)的Session ID来控制文件存储位置
关键代码分析
漏洞修复补丁:官方补丁
补丁主要修改:
- 从仅检测Session ID长度为32
- 增加了
ctype_alnum检查,确保Session ID只包含字母和数字
环境搭建
-
启用
.env配置文件:cp .example.env .env -
启用Session功能:
修改app/middleware.php,取消Session初始化的注释:return [ // 全局请求缓存 // \think\middleware\CheckRequestCache::class, // 多语言加载 // \think\middleware\LoadLangPack::class, // Session初始化 \think\middleware\SessionInit::class ]; -
创建测试控制器:
在app/controller/Index.php中添加测试方法:public function test(){ session('demo', $_GET['c']); }
漏洞复现
-
构造恶意请求:
http://target.com/index/test?c=malicious_content&PHPSESSID=../../../path/to/target/file -
注意Session ID长度必须为32字符,否则会重新设置Session
漏洞利用流程
- 攻击者发送带有恶意Session ID的请求
- 服务器处理Session时调用
setId方法- 第一次调用:读取Session
- 第二次调用:在请求结束时通过
SessionInit->end()->Session->save()
think\Session\Store->save()方法:- 拼接
sess_前缀和Session ID得到文件名 - 创建目录(如果不存在)
- 拼接
- 最终通过
writeFile将Session数据写入文件
防御措施
- 升级到已修复版本
- 严格验证Session ID,确保只包含字母数字字符
- 对文件路径进行规范化处理,防止目录遍历
总结
该漏洞由于Session ID验证不足,导致攻击者可以控制文件存储路径和内容,可能造成任意文件写入甚至远程代码执行。开发者应及时应用补丁或升级框架版本。