yii反序列化漏洞
Yii框架
Yii 是一个适用于开发 Web2.0 应用程序的高性能PHP 框架。
Yii 是一个通用的 Web 编程框架,即可以用于开发各种用 PHP 构建的 Web 应用。 因为基于组件的框架结构和设计精巧的缓存支持,它特别适合开发大型应用, 如门户网站、社区、内容管理系统(CMS)、 电子商务项目和 RESTful Web 服务等。
Yii 当前有两个主要版本:1.1 和 2.0。 1.1 版是上代的老版本,现在处于维护状态。 2.0 版是一个完全重写的版本,采用了最新的技术和协议,包括依赖包管理器 Composer、PHP 代码规范 PSR、命名空间、Traits(特质)等等。 2.0 版代表新一代框架,是未来几年中我们的主要开发版本。
Yii 2.0 还使用了 PHP 的最新特性, 例如命名空间 和Trait(特质)
漏洞描述
Yii2 2.0.38 之前的版本存在反序列化漏洞,程序在调用unserialize 时,攻击者可通过构造特定的恶意请求执行任意命令。CVE编号是CVE-2020-15148。
2.0.38已修复,官方给yii\db\BatchQueryResult类加了一个__wakeup()函数,__wakeup方法在类被反序列化时会自动被调用,而这里这么写,目的就是在当BatchQueryResult类被反序列化时就直接报错,避免反序列化的发生,也就避免了漏洞。
环境复现
本地使用phpstudy进行环境搭建
一定要选到YII安装目录的web目录,端口号重置下。配置好以后 就可以访问了
修改config\web.php中的cookieValidationKey为任意值,作为yii\web\Request::cookieValidationKey的加密值,不设置会报错
由于是反序列化利用链,我们需要一个入口点,在controllers目录下创建一个Controller:
action为:http://url/index.php?r=test/test
controllers/TestController.php
<?php
namespace app\controllers;
use yii\web\Controller;
class TestController extends Controller{
public function actionTest($data){
return unserialize(base64_decode($data));
}
}
漏洞分析
漏洞的出发点是在\yii\vendor\yiisoft\yii2\db\BatchQueryResult.php文件中
/**
* Destructor.
*/
public function __destruct()
{
// make sure cursor is closed
$this->reset();
}
/**
* Resets the batch query.
* This method will clean up the existing batch query so that a new batch query can be performed.
*/
public function reset()
{
if ($this->_dataReader !== null) {
$this->_dataReader->close();
}
$this->_dataReader = null;
$this->_batch = null;
$this->_value = null;
$this->_key = null;
}
正常来说跟进close()方法,但没有找到利用点。但是这里_dataReader是可控的,可以通过触发__call方法来进行利用。
__call(),在对象中调用一个不可访问方法时调用
当一个对象调用不可访问的close方法或者类中没有close方法,即可触发__call。全局搜索一下__call方法,在\vendor\fzaninotto\faker\src\Faker\Generator.php存在合适的方法
public function __call($method, $attributes)
{
return $this->format($method, $attributes);
}
继续跟进format方法
public function format($formatter, $arguments = array())
{
return call_user_func_array($this->getFormatter($formatter), $arguments);
}
call_user_func_array:调用回调函数,并把一个数组参数作为回调函数的参数
使用方法:
call_user_func_array(callable $callback, array $param_arr): mixed
callback
被调用的回调函数。
param_arr
要被传入回调函数的数组,这个数组得是索引数组。
示例:
<?php
namespace Foobar;
class Foo {
static public function test($name) {
print "Hello {
$name}!\n";
}
}
// As of PHP 5.3.0
call_user_func_array(__NAMESPACE__ .'\Foo::test', array('Hannes'));
// As of PHP 5.3.0
call_user_func_array(array(__NAMESPACE__ .'\Foo', 'test'), array('Philip'));
?>
跟进getFormatter
public function getFormatter($formatter)
{
if (isset($this->formatters[$formatter])) {
return $this->formatters[$formatter];
}
foreach ($this->providers as $provider) {
if (method_exists($provider, $formatter)) {
$this->formatters[$formatter] = array($provider, $formatter);
return $this->formatters[$formatter];
}
}
throw new \InvalidArgumentException(sprintf('Unknown formatter "%s"', $formatter));
}
因为$this->formatters是可控的,因此getFormatter方法的返回值也是我们可控的,因此call_user_func_array($this->getFormatter($formatter), $arguments);中,第一个参数可控,第二个参数为空。
这一步就需要一个执行类,这时需要类中的方法需要满足两个条件
- 方法所需的参数只能是其自己类中存在的(即参数:
$this->args) - 方法需要有命令执行功能

本文详细介绍了Yii2框架在2.0.38之前版本存在的反序列化漏洞,该漏洞允许攻击者通过构造恶意请求执行任意命令。文章通过环境复现、漏洞分析和PoC展示,揭示了漏洞的触发点和利用链,涉及yiidbBatchQueryResult、FakerGenerator等类的方法。同时,提供了多个不同版本的exploit示例,包括ctfshow平台上的实战应用。
最低0.47元/天 解锁文章
2014

被折叠的 条评论
为什么被折叠?



