ThinkPHP5.0.x远程执行漏洞

2024-05-15 487 0

参考链接:链接一链接二

漏洞概要

  • 漏洞名称:ThinkPHP 5.0.x-5.1.x 远程代码执行漏洞

  • 参考编号:无

  • 威胁等级:严重

  • 影响范围:ThinkPHP v5.0.x < 5.0.23,ThinkPHP v5.1.x < 5.0.31

  • 漏洞类型:远程代码执行

  • 利用难度:容易

  • payload:?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

漏洞概述

2018年12月10日,ThinkPHPv5系列发布安全更新,修复了一处可导致远程代码执行的严重漏洞。此次漏洞由ThinkPHP v5框架代码问题引起,其覆盖面广,且可直接远程执行任何代码和命令。电子商务行业、金融服务行业、互联网游戏行业等网站使用该ThinkPHP框架比较多,需要格外关注。由于ThinkPHP v5框架对控制器名没有进行足够的安全检测,导致在没有开启强制路由的情况下,黑客构造特定的请求,可直接进行远程的代码执行,进而获得服务器权限。

漏洞分析

前期准备

  1. 为什么从?s=开始

在application/config.php第78行左右有这个定义,var_pathinfo键的默认值就是s

ThinkPHP5.0.x远程执行漏洞插图

搜索一下,发现在thinkphp/library/think/Request.php中有这个键

ThinkPHP5.0.x远程执行漏洞插图1

用Config::get获取了var_pathinfo的值,也就是s的值,然后变成了$_GET['s']然后把值赋给$_SERVER['PATH_INFO'],判断url里是否有兼容模式参数,然后下面$this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');

去除了最左边的正斜杠。得出结论,s就是用来获取payload中的index/\think\app/invokefunction这部分的,而它的值在源码里面就作为pathinfo。知道这个后,继续跟着程序执行流程

执行到thinkphp\library\think\Route.php#check()

ThinkPHP5.0.x远程执行漏洞插图2

其中,$url实际上传入的就是刚才的pathinfo的值。然后$url = str_replace($depr, '|', $url);把所有/换成了|。那么现在就是index|\think\app|invokefunction这个样子。但是因为没有定义好的路由规则,最后还是执行了

ThinkPHP5.0.x远程执行漏洞插图3

之后在thinkphp\library\think\App.php中

ThinkPHP5.0.x远程执行漏洞插图4

可以看到,如果没有定义好路由规则,也就是刚才的return了false,并且还有强制路由的话就会抛出错误。但是这个漏洞利用条件之一就是不开启强制路由~。

那么再往下走,就会到parseUrl

ThinkPHP5.0.x远程执行漏洞插图5

然后parseUrl用parseUrlPath()方法,用$path = explode('/', $url);来把这个url给处理为了一个数组,返回了一个path数组

ThinkPHP5.0.x远程执行漏洞插图6

这样实际上就是分成了模型、控制器、方法了。最终逐个获取的位置是parseUrl方法的:

ThinkPHP5.0.x远程执行漏洞插图7

漏洞原因

当程序执行到thinkphp\library\think\App.php#exec(),会进入到module分支,来到module方法,在:

ThinkPHP5.0.x远程执行漏洞插图8

这里的result数组实际上就是刚才parseUrl返回的那个path数组,

ThinkPHP5.0.x远程执行漏洞插图9

1=>控制器,2=>操作名(也叫做方法名)。在这里获取了之后,程序没有再对控制器、方法名过滤导致了任意控制器下任意方法的调用。然后会使用加载器

ThinkPHP5.0.x远程执行漏洞插图10

加载think\app,在thinkphp\library\think\Loader.php#controller()

ThinkPHP5.0.x远程执行漏洞插图11

然后在invokeClass中使用反射API来动态实例化一个类,并根据提供的参数调用其构造函数。这在需要动态创建对象而不直接使用new关键字时非常有用。

ThinkPHP5.0.x远程执行漏洞插图12

这个函数的作用是把think\app实例化成一个类(描述不准确),然后就可以调用这个类的函数了

返回到了$instance变量中,这时控制器这块已经基本上处理完了,think\App实际上就是thinkphp\library\think\App.php这个php文件里的App类(在MVC架构中,某些类也是可以叫做控制器),think是一个命名空间。意思就是think命名空间下的都是thinkphp的核心代码。

new \ReflectionClass($class):这行代码创建了一个ReflectionClass对象,它用于获取关于给定类的信息,比如它的构造函数、方法、属性等。

$reflect->getConstructor():这行代码获取了类的构造函数。如果类没有定义构造函数,则返回null

$constructor ? self::bindParams($constructor, $vars) : []:这是一个三元运算符。如果$constructor不为null(即类有构造函数),则调用self::bindParams方法,该方法用于将$vars数组中的值绑定到构造函数的参数上。如果$constructornull,则$args数组为空。

$reflect->newInstanceArgs($args):这行代码使用ReflectionClass对象的newInstanceArgs方法来实例化类。这个方法接受一个参数数组,这些参数将传递给类的构造函数。如果之前没有构造函数或者没有提供参数,则不会调用构造函数。

接下来就是获取方法,调用反射执行类的方法。App类里的invokefunction方法使用反射API来动态调用一个函数,并根据提供的参数传递给函数。这在需要动态调用函数而不直接使用函数调用语法时非常有用

ThinkPHP5.0.x远程执行漏洞插图13

它先获取了$function的信息,然后把$vars数组中的参数与函数绑定,然后使用invokeArgs方法调用了这个函数以及绑定的参数

`self::bindParams($reflect, $vars):这行代码调用了一个名为bindParams的静态方法,该方法用于将$vars数组中的值绑定到函数的参数上。$reflect对象提供了函数参数的信息。

self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'):这是一个条件语句,用于记录函数的执行信息。如果self::$debugtrue,则调用Log::record方法记录一条信息日志,其中包含了函数的名称和执行信息。$reflect->__toString()返回函数的名称。

$reflect->invokeArgs($args):这行代码使用ReflectionFunction对象的invokeArgs方法来调用函数。这个方法接受一个参数数组,这些参数将传递给函数。

总结

所以总体流程如下:

  1. 传入的?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami,其中s(var_pathinfo)会取值index/\think\app/invokefunction

  2. s会先处理成为index|\think\app|invokefunction,之后进一步被处理为path数组

  3. 然后进入module函数中,$controller得到值为/think/app,作为参数执行controlle函数

  4. /think/app作为参数在invokeClass函数中被实例化,之后就可以调用,\think\app的函数

  5. 执行了App里的invokeFunction,并给其传入了参数1:function=call_user_func_array,参数2:vars[]=system&vars[1][]=whoami,相当于执行了call_user_func_array('system', ['whoami']),也就是system('whoami')。执行了命令。


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

苹果试图保护你的隐私,OpenAI可能做不到
Shuffle:一款完全自动化的安全栈增强平台
如何使用CODASM编码Payload并降低熵值
SessionExec:一款针对会话安全的安全命令测试工具
Arkime:一款大规模数据包捕获和索引数据库系统
从蓝队流量角度分析Shiro-550反序列化漏洞

发布评论