ThinkPHP 5.1.x~5.2.x全版本 RCE 漏洞分析

大概看了下,这个洞跟5.0的原理大致相同,都是利用Reuqest类的Method方法覆盖了$this->filter属性,然后进入filterValue调用call_user_func($filter, $value)$value当前请求参数和URL地址中的参数合并,从而导致RCE。

漏洞验证

测试版本:Thinkphp_5.1.1
补丁:https://github.com/top-think/framework/commit/2454cebcdb6c12b352ac0acd4a4e6b25b31982e6
需要在入口文件处关闭报错。
图片.png
payload

c=exec&f=calc.exe&&_method=filter&

图片.png

流程分析

在获取应用调度信息时会调用Request类的method方法获取当前的请求类型
图片.png
$this->config->get('var_method')外部可控,即$this->method我们可控,从而我们可以通过$this->{$this->method}($_POST)调用任意方法。
图片.png
图片.png
跟进filter方法,发现我们post的数据可以覆盖$this->filter属性。
图片.png
回到App类,由于我们开启了$this->debug从而可以进入Request类的param方法。
图片.png
跟进param方法,$this->param当前请求参数和URL地址中的参数合并。然后进入input方法。
图片.png
跟进input方法,因为$data为上面提到的$this->param即数组,从而进入if条件执行array_walk_recursive($data, [$this, 'filterValue'], $filter);
图片.png
查阅array_walk_recursive函数可知,该函数会调用$this->filterValue函数,把$data数组的每个值作为其第一个参数,键名作为第二个参数,并且把$this->filter作为第三个参数。
图片.png
继续跟进filterValue方法,发现调用了call_user_func($filter, $value)$filter为刚开始我们覆盖的$this->filter属性的遍历键值,等于$_POST数组。$value当前请求参数和URL地址中的参数合并数组$this->param的键值。
图片.png
当遍历到$this->param的第二个键值calc.exe$filters的第一个键值exec时,成功执行命令,弹出了计算器。
图片.png

补丁分析

图片.png
与5.0一样,对表单请求类型伪装变量添加了白名单。

发表评论

电子邮件地址不会被公开。 必填项已用*标注