Yii2反序列化漏洞复现
CVE-2020-15148
漏洞描述
Yii 是一个通用的 Web 编程框架,即可以用于开发各种用 PHP 构建的 Web 应用。 因为基于组件的框架结构和设计精巧的缓存支持,它特别适合开发大型应用, 如门户网站、社区、内容管理系统(CMS)、 电子商务项目和 RESTful Web 服务等。Yii2 2.0.38 以前的版本中存在反序列化漏洞,CVE编号是CVE-2020-15148
环境搭建
到github上下载yii2的2.0.37版本
打开 /config/web.php
给17行的cookieValidationKey添加一个值,随便什么都行
不添加就会这样
用 php yii serve --port=xxx
启动
显示默认主页,环境搭建成功
2.0.37版本漏洞复现
前置知识
在漏洞复现之前,补充一点yii2框架的前置知识点,yii2调用控制器和方法的格式是
http://url/index.php?r=[控制器]/[方法]
但是这是我们自己搭的环境,什么服务都没有,反序列化也就没有入口点,所以我们自己手动添加一个入口
在 /controllers 文件夹底下创建一个新的控制器,控制器里面写一个新的action方法,执行传入的aaa变量
注意命名空间
然后在网址界面调用这个我们自定义控制器下面的自定义方法
这里的控制器和action方法命名有严格规范,图中可以明显看出来,不做过多解释
上面我们只是测试了一下自定义控制器能不能正常工作,想要写一个自定义的反序列化入口,还是得这么写
<?php
namespace app\controllers;
use yii\web\Controller;
class HahaController extends Controller{
public function actionXixi($aaa){
// return phpinfo();
return unserialize(base64_decode($aaa));
}
}
反序列化链分析
2.0.38版本之前的漏洞是从**/vendor/yiisoft/yii2/db/BatchQueryResult.php里面的BatchQueryResult**类开始的
在开始分析链之前,先看看这些类属性,这些都是可控点,在后面的分析中需要保持敏感
BatchQueryResult类的 __destruct() 是这条链的入口
跟进**reset()**方法
这里调用了 _dataReader的close()方法,这里跟进了close()之后也找不到可以利用的点,但是 _dataReader是BatchQueryResult类的属性,可控,所以我们可以想办法调用一下某个类的 __call() 方法
在框架里面全局搜索有 __call() 方法的类
其中Generator.php里面的Generator就符合我们的要求,老规矩先看看属性部分
Generator的 **__call()**方法
这里的** m e t h o d ∗ ∗ 是 被 调 用 的 那 个 不 存 在 的 方 法 名 , 在 这 里 就 是 ∗ ∗ c l o s e ∗ ∗ , ∗ ∗ method**是被调用的那个不存在的方法名,在这里就是**close**,** method∗∗是被调用的那个不存在的方法名,在这里就是∗∗close∗∗,∗∗attributes**是后面的参数,这里就为空
继续跟进format()方法,这里call_user_func_array已经和目标很接近了
format()方法的两个参数, f o r m a t t e r ∗ ∗ 就 是 上 一 层 的 ∗ ∗ formatter**就是上一层的** formatter∗∗就是上一层的∗∗method,即为close, a r g u m e n t s ∗ ∗ 也 变 成 了 空 数 组 , ∗ ∗ c a l l u s