内容简介:消息刚刚曝出来的时候还以为自己能半天把漏洞给找出来,果然是太菜太年轻了,23333此次漏洞出现在ThinkPHP用于处理HTTP请求的Request类中,其中的method方法用于获取当前的请求类型。
前言
消息刚刚曝出来的时候还以为自己能半天把漏洞给找出来,果然是太菜太年轻了,23333
漏洞分析
漏洞点
此次漏洞出现在ThinkPHP用于处理HTTP请求的Request类中,其中的method方法用于获取当前的请求类型。
thinkphp/library/think/Request.php
var_method
为“表单伪装变量”,可在 application/config.php
中定义:
该变量用于请求类型的伪装,官方文档如下:
由于没有做任何过滤,我们可以通过控制 _method
参数的值来动态调用Request类中的任意方法,通过控制 $_POST
的值来向调用的方法传递参数。
来看一下Request类的构造方法:
thinkphp/library/think/Request.php
该方法将传入的数组进行遍历,如果数组的键名与类的属性名相同,就将对应的值赋给类属性。因此我们可以通过控制post参数来控制Request类的各种属性。
漏洞触发
漏洞点已经找到,那么如何来触发它呢?
5.0.0-5.0.12
payload:
POST /tp5010/public/index.php?s=index/index/index HTTP/1.1 Host: 127.0.0.1:8000 Content-Length: 52 Content-Type: application/x-www-form-urlencoded s=whoami&_method=__construct&filter[]=system
ThinkPHP在解析路由的过程中会调用Request类的method方法:
thinkphp/library/think/Route.php
具体调用流程如下:
此时我们已将类属性成功赋值为我们可控的值,接下来ThinkPHP会处理请求的参数,调用流程如下:
由于我们之前覆盖了Request类的filer属性,该属性用来指定全局过滤函数,所以所有的http参数都会经过过滤函数。
thinkphp/library/think/Request.php
跟进filterValue函数:
可以看到在filterValue方法中调用了call_user_func成功执行了system函数。
5.0.13-5.0.23
在ThinkPHP 5.0.12之后的版本中,在 thinkphp/library/think/App.php
的module方法中增加了设置filter属性的代码:
这样一来我们之前设置的filter属性就会被重新覆盖为空,导致之前的payload失效,必须寻找新的触发点。
我们回看上面的调用过程,发现Request类中的param方法也调用了method方法:
当method参数为true时,会进入server方法,跟进看一下:
继续跟进input方法:
可以看出Request类的server属性是一个数组,并且是可控的,这里input方法将key为REQUEST_METHOD的成员取出来放入了filterValue方法。这里我们需要找到调用Request类的param方法的地方来触发漏洞。
开启了debug模式
如果debug模式开启,在 thinkphp/library/think/App.php
的run方法中会记录路由和请求信息,此处调用了param方法。
由于此时还没有执行到module方法,所以filter属性仍是我们设置的值,没有被重新赋值。
payload:
POST /tp5023/public/index.php HTTP/1.1 Host: 127.0.0.1:8000 Content-Type: application/x-www-form-urlencoded Content-Length: 70 _method=__construct&filter[]=system&server[REQUEST_METHOD]=id
有直接路由到控制器类或者方法的路由规则
payload:
POST /tp5023/public/index.php/?s=captcha HTTP/1.1 Host: 127.0.0.1:8000 Content-Type: application/x-www-form-urlencoded Content-Length: 72 _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id
根据前面的分析,我们知道之前的payload失效的原因是在 thinkphp/library/think/App.php
的module方法中增加了设置filter属性的代码,那么我们可不可以不执行module方法而执行其他方法呢?
thinkphp/library/think/App.php
可以看到exec方法通过 $dispatch['type']
来决定调用哪个方法,在调用controller和method方法时都调用了Request类的param方法。现在来看一下 $dispatch
是从哪来的:
跟进routeCheck方法:
从配置文件中读取了路由配置后导入,然后进入了Route类的check方法。
thinkphp/library/think/Route.php
这里调用了我们熟悉的method方法,这里就是我们进行变量覆盖的地方,再来看一下method方法:
在我们覆盖了类属性之后,直接将method属性返回了。获取到method之后,会根据method的值到 self::$rule
中获取相应的路由规则。
由于ThinkPHP有自动加载机制,在运行时会自动加载 vendor
目录下的第三方库。加载过程如下:
其中ThinkPHP 完整版 中有一个验证码的第三方库,在被加载的时候会注册一条路由规则,当我们访问 http://xxx/captcha
时会路由到 \think\captcha\CaptchaController
的index方法。
vendor/topthink/think-captcha/src/helper.php
回到 thinkphp/library/think/Route.php
ThinkPHP会解析这条路由规则,解析过程如下:
由于这条规则是直接路由到控制器类的方法,所以type为method。
再回到 thinkphp/library/think/App.php
的exec方法,可以看到已经能够执行param方法,达到了rce的目的。
漏洞防御
thinkphp/library/think/Request.php
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 漏洞分析:OpenSSH用户枚举漏洞(CVE-2018-15473)分析
- 【漏洞分析】CouchDB漏洞(CVE–2017–12635, CVE–2017–12636)分析
- 【漏洞分析】lighttpd域处理拒绝服务漏洞环境从复现到分析
- 漏洞分析:对CVE-2018-8587(Microsoft Outlook)漏洞的深入分析
- 路由器漏洞挖掘之 DIR-815 栈溢出漏洞分析
- Weblogic IIOP反序列化漏洞(CVE-2020-2551) 漏洞分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
谷歌和亚马逊如何做产品
梅 (Chris Vander Mey) / 刘亦舟 / 人民邮电出版社 / 2014-6-1 / CNY 49.00
软件在交付之前,面临产品、方案、项目和工程管理等诸多挑战,如何做到游刃有余并打造出极致产品?本书作者曾任谷歌和亚马逊高级产品经理、现任Facebook产品经理,他将自己在达特茅斯学院钻研的理论知识和在领先的互联网公司十年的工作经验尽数总结在此,从定义产品开始,一步步指导你完成管理项目、迭代、发布、市场推广等交付流程,让你身临其境地体验到极致产品如何取得成功。 本书主要内容: 如何清晰定......一起来看看 《谷歌和亚马逊如何做产品》 这本书的介绍吧!