yii2框架 反序列化漏洞复现

您所在的位置:网站首页 灯泡保护电路 yii2框架 反序列化漏洞复现

yii2框架 反序列化漏洞复现

2023-12-10 21:13| 来源: 网络整理| 查看: 265

前言

最近学习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()

构造一波:



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3