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

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

缺陷编号:wooyun-2013-040506

漏洞标题:cmseasy盲注漏洞

相关厂商:cmseasy

漏洞作者: Chora

提交时间:2013-10-21 13:13

修复时间:2014-01-19 13:14

公开时间:2014-01-19 13:14

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-10-21: 细节已通知厂商并且等待厂商处理中
2013-10-21: 厂商已经确认,细节仅向厂商公开
2013-10-24: 细节向第三方安全合作伙伴开放
2013-12-15: 细节向核心白帽子及相关领域专家公开
2013-12-25: 细节向普通白帽子公开
2014-01-04: 细节向实习白帽子公开
2014-01-19: 细节向公众公开

简要描述:

cmseasy盲注漏洞

详细说明:

出错的是一个通用函数,所以注入不只一处,在这里就用能够相对简单利用的来写。
lib/default/ballot_act.php

function index_action() {
if (front::post('submit')) {
if (!front::post('ballot')) {
front::alert(lang('Please_select_vote'));
return false;
}
/*
if (config::get('checkip')) {
$time=cookie::get('vttime');
if (time() -$time <config::get('timer') * 60) {
front::alert(lang('You_have_voted'));
return false;
}

}*/
$bid=front::$post['bid'];
if (is_array(front::$post['ballot'])) {
$ids=implode(',',front::$post['ballot']);
}
else {
$ids=front::$post['ballot'];
}
if(preg_match('/(select|union|and|\'|"|\))/i',$ids)){ //只是检查了$ids并没有检查$bid。读代码眼睛读花了还真看不错来- -。
exit('非法参数');
}
$where="id in($ids)";
$data='num=num+1';
$option=new option();
$option->rec_update($data,$where);
$this->_table->rec_update($data,$bid); //跟进 0x01
//1 and if(1=1,BENCHMARK(1000000,MD5(1)),null)
//UPDATE `cmseasy_ballot` SET num=num+1 WHERE and if(1=1,BENCHMARK(1000000,MD5(1)),null) 延时3秒左右。
//UPDATE `cmseasy_ballot` SET num=num+1 WHERE and if(1=2,BENCHMARK(1000000,MD5(1)),null)
cookie::set('vttime',time(),time() +3600 * 24);
front::alert(lang('Successful_vote'));
}
}


lib/inc/table.php 0x01

function rec_update($row,$where) {
$tbname=$this->name;
$sql=$this->sql_update($tbname,$row,$where); //跟进
//echo $sql."<br>";
return $this->query_unbuffered($sql) or die(mysql_error());
}
function sql_update($tbname,$row,$where) {
$sqlud='';
if (is_string($row))
$sqlud=$row.' ';
else
foreach ($row as $key=>$value) {
if (in_array($key,explode(',',$this->getcolslist()))) {
$value=$value;
if (preg_match('/^\[(.*)\]$/',$value,$match))
$sqlud .= "`$key`"."= ".$match[1].",";
elseif ($value === "")
$sqlud .= "`$key`= NULL, ";
else
$sqlud .= "`$key`"."= '".$value."',";
}
}
$sqlud=rtrim($sqlud);
$sqlud=rtrim($sqlud,',');
$this->condition($where);//问题处在这儿,跟进
$sql="UPDATE `".$tbname."` SET ".$sqlud." WHERE ".$where;
return $sql;
}
function condition(&$condition) {
if (isset($condition) &&is_array($condition)) { //不是数组跳过
$_condition=array();
foreach ($condition as $key=>$value) {
$value=str_replace("'","\'",$value);
$_condition[]="`$key`='$value'";
}
$condition=implode(' and ',$_condition);
}
else if (is_numeric($condition)) { //不是数字跳过
$this->getFields();
$condition="`$this->primary_key`='$condition'";
}else if(true === $condition){ //错在这儿,程序员本意是如果值为真就把'true'赋值给$condition,这样不是数组又不是数字的就过滤了,但是他用了3个等号,全等,类型也要匹配才会赋值,所以这里跳过了赋值,所以悲剧发生了,只要用到condition这个函数的都会悲剧。
//很多关键的数据库操作都调用了该函数,慢慢找还会有很多注入的。建议改成2个等号修复该函数而不是过滤这个投票的参数。
$condition = 'true';
}
if (get_class($this) == 'archive') {
if (!front::get('deletestate')) {
if ($condition)
$condition.=' and (state IS NULL or state<>\'-1\') ';
else
$condition='state IS NULL or state<>\'-1\' ';
}
else {
if ($condition)
$condition.=' and state=\'-1\' ';
else
$condition=' state=\'-1\' ';
}
}
}

漏洞证明:

1.JPG


2.JPG

修复方案:

继续求包养。

版权声明:转载请注明来源 Chora@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2013-10-21 13:15

厂商回复:

感谢,尽快修正

最新状态:

暂无