ThinkPHP 5.0命令执行漏洞分析与复现
ThinkPHP 5.0版本是一个颠覆和重构版本,也是ThinkPHP十周年献礼版本,基于PHP5.4设计(完美支持PHP7),采用全新的架构思想,引入了很多的PHP新特性,优化了核心,减少了依赖,支持Composer,实现了真正的惰性加载,并且为API开发做了深入的支持,在功能、性能以及灵活性方面都较为突出。
0X01 漏洞描述
ThinkPHP5.0在核心代码中实现了表单请求类型伪装的功能,该功能利用$_POST[‘_method’]变量来传递真实的请求方法,当攻击者设置_$POST[‘_method’]=__construct时,Request类的method方法便会将该类的变量进行覆盖,攻击者利用该方法将filter变量覆盖为system等函数名,当内部进行参数过滤时便会进行任意命令执行。
0X02影响范围
ThinkPHP 5.0.0 ~ ThinkPHP 5.0.23
0X03什么是表单请求类型伪装
1 | <form method="post" action=""> |
如上表单,可以的POST表单里面提交_method变量,传入需要伪装的请求类型,该请求从客户端看来是POST请求,而服务器会将该请求识别PUT请求并进行处理,其中变量_method可以在application\config.php文件中进行修改。
//表单请求类型伪装变量
‘var_method’ =>’_method’
该特性的作用:
安全防护,隐藏自己真实请求信息;
整合现有应用系统,例如现有的应用系统A的接口只接受put请求,而你的应用系统B只能发起post请求。
0X04 漏洞环境
环境
OS :windows10
Webserver:phpstudy(apache+php5.6.27)
thinkphp:5.0.20
条件
//应用调试模式
‘app_debug’ =>true,
操作
cd D:\phpStudy\WWW
git clone https://github.com/top-think/think tp5
cd tp5
git clone https:// github.com/top-think/framework thinkphp
git checkout v5.0.22
开启thinkphp的debug模式
//开启thinkphp的调试模式,文件application\config.php
//应用调试模式
‘app_debug’ =>true,
开启Apache,发送payload
0X05漏洞分析
利用xdebug+phpstorm进行调试。
thinkphp采用filter对请求参数进行过滤,默认的filter在config.php中为空字符串,thinkphp首先会设置默认的过滤参数:
filter被设置为空字符串,继续跟踪在路由检查内部会对Request类的filter变量进行覆盖,跟进routeCheck函数。
再上图中调用$requesr->method()关键方法,跟进:
能够发现该函数会获取用户传入的_method=__construct变量,并调用__construct方法,跟进:
filter变量被设置为system,继续:
当debug模式开启时,会记录请求信息,会调用$request->param()方法,跟进:
如上,根据filter变量设置过滤器,跟进:
过滤器变成了数组[‘system’],跟进array_walk_recursive函数:
该函数内会对参数进行过滤,调用了call_user_func(‘system’, ‘dir’),完成了命令执行,结果如下:
接下来,thinkphp在执行模块的过程中还会再一次设置默认filter,使得filter=''
,但是不会再次覆盖filter为system,所以接下来的一次过滤并没有能够再次执行命令。
整个流程如下:
- 本文作者: y0lo
- 本文链接: http://example.com/2020/10/31/ThinkPHP5-x-远程命令执行漏洞分析与复现/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!