一环境
环境准备环境搭建
yii版本2.0.37和2.0.38
php版本 7.1
下载完打包,直接在
php yii serve
访问localhost:8080
二.分析漏洞
漏洞出发点
在\yii\vendor\yiisoft\yii2\db\BatchQueryResult.php文件中,
跟进reset
我们这里的_dataReader可控,然后$this->_dataREader->close(),触发__call方法(访问不存在的方法时触发)。
在\yii\vendor\fzaninotto\faker\src\Faker\Generator.php中找到一处
跟进format
我们可以控制第一个参数,为什么呢?
我们看一个demo
<?php
class Test
{
function __call($function_name, $args)
{
echo "你所调用的函数:$function_name(参数:<br />";
var_dump($args);
echo ")不存在!";
}
}
// 调用不存在的方法
$p1=new Test();
$p1->test(2,"test");
相当于close为第一个参数,但是第二个参数为空无法控制。
继续跟进getFormatter,此时的$formatter为close,但是第二个数组我们无法控制。
可以看出最后返回
t
h
i
s
−
>
f
o
r
m
a
t
t
e
r
s
[
this->formatters[
this−>formatters[formatter],相当于this->formatters[‘close’],我们是可以控制的,往上推,相当于
call_user_func_array($this->formatters['close'],不可控)
看一下这个函数的用处
这个函数的第一个参数可控,第二个参数为空
现在可以调用yii框架中的任何一个无参的方法。
如果无参方法中出现危险函数并且数据可控我们就可以实现rce。
找调用了call_user_func函数的无参方法。
构造正则
function \w+\(\) ?\n?\{(.*\n)+call_user_func
最后的链子
yii\db\BatchQueryResult::__destruct() -> Faker\Generator::__call() -> yii\rest\IndexAction::run()
不难,然后进行单步调试跟着链子走一遍就行。