内容简介:主要成因为框架中的核心类 Request 中存在调用任意(其实不能算是任意)方法的点,通过构造可以做成 RCE。这是 ThinkPHP 最近出的第二个影响比较大的 RCE 了,虽然对 ThinkPHP 不熟悉,不过这个洞的成因和利用还是比较有意思的,再加上已经好久没去分析 PHP 方面的漏洞了,写下分析当个记录了。全程是根据别人的分析静态跟代码加上在环境上测试完成的,没有做动态跟踪(懒得去弄了)。5.0 - 5.0.23
主要成因为框架中的核心类 Request 中存在调用任意(其实不能算是任意)方法的点,通过构造可以做成 RCE。
这是 ThinkPHP 最近出的第二个影响比较大的 RCE 了,虽然对 ThinkPHP 不熟悉,不过这个洞的成因和利用还是比较有意思的,再加上已经好久没去分析 PHP 方面的漏洞了,写下分析当个记录了。全程是根据别人的分析静态跟代码加上在环境上测试完成的,没有做动态跟踪(懒得去弄了)。
0x00 影响版本
5.0 - 5.0.23
0x01 漏洞分析及利用构造
进入到漏洞关键点的执行流程:
thinkApp#run --> thinkApp#routeCheck --> thinkRoute#check --> thinkRequest#method
thinkRequest#method 具体代码如下
在前面的执行流程中调用到 method 方法的时候是不带参数的,所以这里的形参 $method 的实际值为 false,另外 Config::get('var_method') 的值来自于 convention.php 默认为 _method。虽然这里会把字符串变成大写,但是在 PHP 中方法名大小写不敏感,因此在图中的红框处就能实现 Request 中任意方法的调用(当然了得参数类型符合)。
这里选择的类 Request 中的方法为其构造方法,具体代码如下
选择这个方法主要是为了覆盖类 Request 中的成员变量的值,为后面的利用做准备。
再看 thinkRequest#param
当 mergeParam 为空时会调用到 get 方法,因为 mergeParam 默认不为空,后面是通过覆盖 mergeParam 的值为空让执行流程如设计好的走下去。但不覆盖它为空往下的流程也差不多,只是在利用的时候控制下边要提到的 value 的方法就不一样了。跟进 thinkRequest#get
继续跟进 thinkRequest#input
data 的值来自 Request 中的 get(数组),所以会调用到 array_walk_recursive 函数,而这个函数设置的 callback 函数为 filterValue。漏洞的利用点就在 filterValue 中,其代码如下
主要就是用 call_user_func 来做成 RCE,因此 filter 和 value 的值需要可控,顺着调用流程往回看和结合前面提到的在构造方法中做覆盖的方法就能知道怎么去控制这两个变量的值。结合前面提到的 value 的值其实就来自于 Request 类中的 get,再来看 filter,很明显能知道 filter 的值来自 getFilter 方法的执行结果,thinkRequest#getFilter
这个方法的代码逻辑比较简单的,要控制 filter 的值的话,就只需要在 POST 请求中传个 filter 的值就行了。到这里可以知道的了 PoC 中需要构造的请求如下
POST _method=__construct&mergeParam&=filter=system&get[]=id
接下来只要找到办法调用 thinkRequest#param 就可以完成整个利用了。thinkApp#run 中存在如下代码
所以要是在开启了调试模式的情况下用前面的构造好的请求就可以完成利用了,但是 23 版本在默认情况下是没有开启调试模式的,再看下在没有开启调试模式的情况下如何利用。
回看 thinkRoute#check 中调用 thinkRequest#method 往后的代码
这里的 method 的值其实就来自于 Request 类中的 method,因此可控。往下就是根据 method 的值来获取路由规则,这里需要用到验证码类(只在完整版中有,核心版中没有)中的一个路由规则,规则如下
所以要是想获取到这个路由规则就得传参 s=captcha 来完成类的自动加载同时设置 method 的值为 get。这里获取这个路由规则的主要目的是为了完成漏洞的利用,往下跟就明白了。接下来的执行流程为 thinkRoute#checkRoute --> thinkRoute#checkRule --> thinkRoute#parseRule
parseRule 方法中的部分代码
这里主要是根据路由规则的格式返回不同的结果,这里返回的结果中 type 为 method。结果返回赋值给 thinkApp 类中的 dispatch。往下跟进 thinkApp#exec
可以看到这里就能成功调用到了漏洞利用需要的 param 方法。
0x02 PoC
开启调试模式
POST /index.php _method=__construct&mergeParam&=filter=system&get[]=id
关闭调试模式
POST /index.php?s=captcha _method=__construct&mergeParam&=filter=system&get[]=id&method=get
另外一种控制 value 的方法
_method=__construct&filter=system&server[REQUEST_METHOD]=id&method=get
0x03 参考
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ThinkPHP5 RCE
- thinkphp5.0 RCE分析
- thinkphp5 RCE漏洞重现及分析
- ThinkPHP5 RCE漏洞重现及分析
- 天融信关于ThinkPHP5.1框架结合RCE漏洞的深入分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Delivering Happiness
Tony Hsieh / Grand Central Publishing / 2010-6-7 / USD 27.00
http://www.deliveringhappinessbook.com/ The visionary CEO of Zappos explains how an emphasis on corporate culture can lead to unprecedented success. Pay new employees $2000 to quit. Make custome......一起来看看 《Delivering Happiness》 这本书的介绍吧!