yii2框架 反序列化漏洞复现

本文详细介绍了Yii2框架在2.0.38之前版本存在的反序列化漏洞,通过复现CVE-2020-15148,展示了如何利用__destruct、__call、__toString等魔术方法进行远程代码执行。文章讲解了不同利用链的挖掘过程,包括BatchQueryResult、RunProcess和DiskKeyCache类,并提供了相应的POC构造,揭示了在不同版本中寻找和利用反序列化链的思路。

前言

最近学习PHP反序列化的时候遇到了yii2反序列化的利用,就顺便搭了一下环境,跟着网上各种大师傅们的文章进行了一波复现和学习,提高自己代码审计的能力。

漏洞出现在yii2.0.38之前的版本中,在2.0.38进行了修复,CVE编号是CVE-2020-15148:

Yii 2 (yiisoft/yii2) before version 2.0.38 is vulnerable to remote code execution if the application calls unserialize() on arbitrary user input. This is fixed in version 2.0.38. A possible workaround without upgrading is available in the linked advisory.

至于环境的安装,直接从github上找yii2,下载下来2.0.37版本,然后修改config/web.php文件里cookieValidationKey的值,随便什么值都行。然后正常的部署一下就行了,就像thinkphp那样,根目录是/yii2/web。

CVE-2020-15148复现

这个反序列化的入口点是一个__destruct(),在BatchQueryResult类中
在这里插入图片描述
继续跟进一下reset():
在这里插入图片描述
但是继续跟进close(),发现没有什么利用的办法,正常可能链就断了,但是大师傅们的思路就是不一样,这里的_dataReader是可控的,那么调用了close的方法,是不是可以想办法触发__call呢?

全局搜索一下__call,最后在\vendor\fzaninotto\faker\src\Faker\Generator.php找到了一个合适的__call方法:
在这里插入图片描述
因为close是无参方法,所以__call中的$method是close,attributes为空。继续跟进format方法:
在这里插入图片描述
看到call_user_func_array的时候肯定就很兴奋了。继续跟进一下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);中,回调函数是我们可控的,但是$arguments为空,所以相当于我们现在能干两件事,可以调用yii2中任意的一个无参方法,或者调用原生php的类似phpinfo()这样的无参方法,但是第二种肯定不能RCE,因此还要在yii2中已有的无参方法中进行挖掘:

function \w+\(\)

在这里插入图片描述
但是无参函数实在是太多了,一个一个挖起来实在费力。这里就是大师傅们的经验和智慧了,直接搜索含有call_user_function的无参函数:

function \w+\(\) ?\n?\{
   
   (.*\n)+call_user_func

但是这个正则在我这里查不到,我感觉我这里的phpstorm搜索好像有点问题。
最后找到的rest/CreateAction.php以及rest/IndexAction.php都很好用。这里分析一下IndexAction.php:
主要是它的run方法:
在这里插入图片描述
太直接了,$this->checkAccess$this->id都是我们可控的,相当于直接函数名和参数都可控了,反序列化链至此结束。

理一下就是这样:

class BatchQueryResult  ->__destruct()
↓↓↓
class BatchQueryResult  ->reset()
↓↓↓
class Generator  ->__call()
↓↓↓
class Generator  ->format()
↓↓↓
class Generator  ->getFormatter()
↓↓↓
class IndexAction  ->run()
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值