Thinkphp3.2.3-漏洞审计汇总
字数 1304 2025-08-12 11:34:39
ThinkPHP 3.2.3 漏洞审计与安全分析
目录结构
入口文件(应用对外提供的接口)
核心框架目录
模块集合(Common模块优先于其他模块执行)
缓存目录(./Application/Runtime)
公共资源目录(./Public)
MVC架构
- 控制器(Controller): 负责用户请求的调度和处理业务逻辑
- 模型(Model): 负责业务数据的处理和与数据库的交互
- 视图(View): 提供了展示数据的各种方式
路由模式
- 普通模式:
http://网址/index.php?m=模块名称&c=控制器&a=方法 - 兼容模式:
http://网址/index.php?s=/模块/控制器/方法 - REWRITE模式:
http://网址/模块/控制器/操作方法 - PATHINFO模式:
http://网址/index.php/模块/控制器/操作方法
SQL注入漏洞分析
1. Where注入
漏洞原理: 当传入数组参数时,$options和$this->options未区分,导致参数污染控制SQL语句。
Payload:
thinkphp_3.2.3/index.php/home/index/shy?id[where]=1 and 1=updatexml(1,concat(0x7e,(select password from users limit 1),0x7e),1)%23
漏洞分析:
- 传入数组参数
id[where] - 绕过
_parseType()的类型转换检查 - 直接拼接SQL语句,未进行有效过滤
修复方案: v3.2.4将$options和$this->options进行了区分
2. Exp注入
Payload:
?username[0]=exp&username[1]==1 and updatexml(1,concat(0x7e,user(),0x7e),1)
关键点:
- 必须使用超全局数组传参,避免I函数的过滤
$val[0]为"exp"时,直接拼接$val[1]到SQL语句
3. Bind注入
Payload:
?id[0]=bind&id[1]=0 and updatexml(1,concat(0x7e,user(),0x7e),1)&password=1
漏洞原理:
$exp为"bind"时,$whereStr部分可控- 通过参数绑定和替换机制绕过过滤
- 最终形成可执行的恶意SQL语句
RCE漏洞分析
文件包含导致RCE
利用条件:
- 模板赋值方法assign的第一个参数可控
- 需要知道日志文件路径
Payload:
index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/22_08_03.log
漏洞流程:
- 通过assign方法覆盖模板变量
- 在模板渲染过程中,使用extract覆盖
$_filename - 包含恶意日志文件执行代码
注意点:
- Debug开启时日志路径不同
- 使用fetch方法需要代码末尾加exit()/die()
日志泄露漏洞
路径结构:
Application/Runtime/Logs/Home/年份_月份_日期.log (Debug开启)
Application/Runtime/Logs/Common/年份_月份_日期.log (Debug关闭)
风险:
- 泄露敏感信息
- 可能包含执行代码
安全建议
- 升级到最新版本(至少v3.2.4)
- 严格过滤用户输入,特别是数组参数
- 关闭Debug模式生产环境
- 限制日志目录访问权限
- 对模板变量进行严格校验
参考资源
- ThinkPHP3.2官方手册: http://document.thinkphp.cn/manual_3_2.html
- 漏洞修复commit: https://github.com/top-think/thinkphp/commit/9e1db19c1e455450cfebb8b573bb51ab7a1cef04
- 相关分析文章:
- https://mp.weixin.qq.com/s/_4IZe-aZ_3O2PmdQrVbpdQ
- https://blog.csdn.net/Mruos/article/details/109802121
- https://www.cnblogs.com/lingzhisec/p/15728886.html