漏洞名称
ThinkPHP 5.0.*远程代码执行漏洞
影响范围
ThinkPHP 5.0.全版本
分析
跟着大佬的脚步笔者简单的分析了下。
Thinkphp处理请求的关键类为Request(thinkphp/library/think/Request.php)
其中成员函数method用来获取当前请求类型,其定义如下:
该函数主要在其他成员函数(例如isGet、isPost、isPut等)中被用来做请求类型判断
thinkphp支持配置“表单伪装变量”,默认情况下该变量值为_method
因此在method()中,可以通过“表单伪装变量”进行变量覆盖实现对该类任意函数的调用,并且$_POST作为函数的参数传入
Request类的构造函数定义如下
构造函数中,主要对$option数组进行遍历,当$option的键名为该类属性时,则将该类同名的属性赋值为$options中该键的对应值。
因此可以构造请求如下,来实现对Request类属性值的覆盖,例如覆盖filter属性。filter属性保存了用于全局过滤的函数。
因此在thinkphp 5.0.10 中可以通过构造如下请求实现代码执行:
但是笔者测试了所有版本后发现一个问题
那就是这个漏洞并不通杀
笔者后续对比了官方多个发布的5.0版本,大概总结出如下结论
版本名 | 是否可被攻击 | 攻击条件 |
---|---|---|
5.0.0 | 否 | 无 |
5.0.1 | 否 | 无 |
5.0.2 | 否 | 无 |
5.0.3 | 否 | 无 |
5.0.4 | 否 | 无 |
5.0.5 | 否 | 无 |
5.0.6 | 否 | 无 |
5.0.7 | 否 | 无 |
5.0.8 | 是 | 无需开启debug |
5.0.9 | 是 | 无需开启debug |
5.0.10 | 是 | 无需开启debug |
5.0.11 | 是 | 无需开启debug |
5.0.12 | 是 | 无需开启debug |
5.0.13 | 是 | 需开启debug |
5.0.14 | 是 | 需开启debug |
5.0.15 | 是 | 需开启debug |
5.0.16 | 是 | 需开启debug |
5.0.17 | 是 | 需开启debug |
5.0.18 | 是 | 需开启debug |
5.0.19 | 是 | 需开启debug |
5.0.20 | 否 | 无 |
5.0.21 | 是 | 需开启debug |
5.0.22 | 是 | 需开启debug |
5.0.23 | 是 | 需开启debug |
之前看很多人复现时选的版本是5.0.13~5.0.19的,这些版本默认情况下config中的app_debug配置项为false,这也是为什么很多人用payload都无法复现
总结
在版本低于5.0.13的版本中,破坏性还是很强的,因为无需开启debug模式即可造成代码执行
在版本高于5.0.20的版本中,破坏性还是一般的,需开启debug模式才可造成代码执行
关于为什么5.0.7及以下版本不能执行,笔者对比了thinkphp\library\think\Route.php,发现5.0.8相对于5.0.7在获取当前请求类型的路由规则处增加了一个三目运算符导致$rules数组被置空
这也解释了为什么5.0.7执行时会爆出如下错误
附赠2个payload
ThinkPHP 5.0测试工具的下载链接请在本公众号回复“TP”获取。
免责声明:工具只能用于测试漏洞,禁止用于非法用途,否则一切后果自负。
作者:Sp4ce 来源:bbs.ichunqiu.com