来源:自学PHP网 时间:2015-04-15 14:59 作者: 阅读:次
[导读] 出错的是一个通用函数,所以注入不只一处,在这里就用能够相对简单利用的来写。lib default ballot_act phpfunction index_action() { if (front::post( 39;submit 39;)) {...
出错的是一个通用函数,所以注入不只一处,在这里就用能够相对简单利用的来写。
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\' '; } } }
|
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com