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

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

缺陷编号:wooyun-2014-063652

漏洞标题:CmsEasy最新版SQL注入(同一文件多处)

相关厂商:cmseasy

漏洞作者: xfkxfk

提交时间:2014-06-06 18:28

修复时间:2014-09-04 18:30

公开时间:2014-09-04 18:30

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

CmsEasy最新版SQL注入(同一文件多处)

详细说明:

与: WooYun: CmsEasy最新版本无限制SQL注射 重复
CmsEasy_5.5_UTF-8_20140420
官方最新包
文件/lib/default/union_act.php
此文件存在多处SQL注入
第一处SQL注入,在联盟注册处:
http://localhost/cmseasy5.5/index.php?case=union&act=register

function register_action() {
$r = $this->_union->getrow(array('userid'=>$this->view->data['userid']));
if($r) {
echo '<script type="text/javascript">alert("'.lang('你已经申请,转入联盟页面!').'")</script>';
front::refresh(url::create('union/stats'));
}
if(front::post('submit')) {
if(!config::get('reg_on')) {
front::flash(lang('网站已经关闭注册!'));
return;
}
if(config::get('verifycode')) {
if(!session::get('verify') ||front::post('verify')<>session::get('verify')) {
front::flash(lang('验证码错误!'));
return;
}
}
if(front::post('nickname') != strip_tags(front::post('nickname'))
||front::post('nickname') != htmlspecialchars(front::post('nickname'))
) {
front::flash(lang('姓名不规范!'));
return;
}
if(strlen(front::post('nickname'))<4) {
front::flash(lang('请填写认真填写真实姓名!'));
return;
}
if(strlen(front::post('payaccount'))<1) {
front::flash(lang('请填写支付账号!'));
return;
}
if(strlen(front::post('tel'))<1) {
front::flash(lang('请填写联系电话!'));
return;
}
if(strlen(front::post('address'))<1) {
front::flash(lang('请填写联系地址!'));
return;
}
if(strlen(front::post('website'))<1) {
front::flash(lang('请填写网站地址!'));
return;
}
/*if(strlen(front::post('e_mail'))<1) {
front::flash(lang('请填写邮箱!'));
return;
}*/
if(is_array($_POST)){
foreach ($_POST as $v){
if(preg_match('/(select|load_file|\[|password)/i', $v)){
exit('not access');
}
}
}
$userarr = array();
$userarr['nickname'] = front::$post['nickname'];
$userarr['tel'] = front::$post['tel'];
$userarr['address'] = front::$post['address'];
//$userarr['e_mail'] = front::$post['e_mail'];
$unionarr = array();
$unionarr['userid'] = $this->view->data['userid'];
$unionarr['username'] = $this->view->data['username'];
$unionarr['payaccount'] = front::$post['payaccount'];
$unionarr['website'] = front::$post['website'];
$unionarr['profitmargin'] = union::getconfig('profitmargin');
$unionarr['regtime'] = time();
$unionarr['regip'] = front::ip();
$unionarr['passed'] = 1;
if(front::post('nickname') &&$this->view->data['userid']) {
$insert=$this->_user->rec_update($userarr,'userid='.$this->view->user['userid']);
$insert1 = $this->_union->rec_insert($unionarr);
if($insert &&$insert1) front::flash(lang('申请成功!'));
else {
front::flash(lang('申请失败!'));
return;
}
front::redirect(url::create('union/stats'));
exit;
}
else {
front::flash(lang('申请失败!'));
return;
}
}
}


$unionarr['regip'] = front::ip();
我们来看看这里的ip()函数:

static function ip() {
if ($_SERVER['HTTP_CLIENT_IP']) {
$onlineip = $_SERVER['HTTP_CLIENT_IP'];
}
elseif ($_SERVER['HTTP_X_FORWARDED_FOR']) {
$onlineip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
elseif ($_SERVER['REMOTE_ADDR']) {
$onlineip = $_SERVER['REMOTE_ADDR'];
}
else {
$onlineip = $_SERVER['REMOTE_ADDR'];
}
if(config::get('ipcheck_enable')){
if(!preg_match('/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $onlineip)&&!preg_match('@^\s*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?\s*$@', $onlineip)){
exit('来源非法');
}
}
return $onlineip;
}


这里的正则存在问题,最后一句的(%.+),这里我们在IP后面加上%,然后就能跟上任意内容
那么我们使用1.1.1.1%xxx就能绕过正则进行注入了。
第二处SQL注入:

function into_action() {
preg_match_all("/case=union&act=into&(.*)/isu",$_SERVER['QUERY_STRING'],$queryout);
if(!empty($queryout[1][0])) {
$userid = intval($queryout[1][0]);
$r = $this->_union->getrow(array('userid'=>$userid));
if($r) {
$time = time() -3600*24;
$unionvisit = new union_visit();
$r_visit = $unionvisit->rec_select("userid=$userid AND visitip='".front::ip()."' AND visittime>$time",0,'*',' 1');
if(!$r_visit) {
$rewardtype = union::getconfig('rewardtype');
$rewardnumber = union::getconfig('rewardnumber');
$user = $this->_user->getrow(array('userid'=>$userid));
$user['username'];
switch($rewardtype) {
case 'point':
union::pointadd($user['username'],$rewardnumber,'union');
break;
}
$useridarr = array();
$useridarr['userid'] = $userid;
$updatevisit = $this->_union->rec_update(array('visits'=>'[visits+1]'),$useridarr);
if($this->_union->affected_rows()) {
$useridarr['userid'] = $userid;
$useridarr['visittime'] = time();
$useridarr['visitip'] = front::ip();
$useridarr['referer'] = $_SERVER['HTTP_REFERER'];
if(preg_match('/select/i',$useridarr['referer']) || preg_match('/union/i',$useridarr['referer']) || preg_match('/"/i',$useridarr['referer']) ||preg_match('/\'/i',$useridarr['referer'])){
exit('非法参数');
}
$unionvisit->rec_insert($useridarr);
$union_visitid = $unionvisit->insert_id();
$cookietime = time() +union::getconfig('keeptime');
cookie::set('union_visitid',$union_visitid,$cookietime);
cookie::set('union_userid',$userid,$cookietime);
}
}
}
}
$url = union::getconfig('forward') ?union::getconfig('forward') : config::get('site_url');
header('location:'.$url);
}


$useridarr['visitip'] = front::ip();

漏洞证明:

第一步:
首先注册两个用户111111,222222
他们的userid分别为2,3(因为admin占了一个id)
第二步:
登陆用户111111
然后注册联盟

1.png


第三步
抓包,修改头信息,添加:

X-Forwarded-For: 1.1.1.1%','1'),('3',user(),user(),user(),'2','1','1.1.1.1','1')#','1')


2.png


第四步
登陆用户222222,然后进入会员中心,联盟推广,修改资料

3.png


注入内容显示在支付账户和网站地址处

修复方案:

严格控制正则,进入sql时对value进行过滤等。

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2014-06-07 13:35

厂商回复:

感谢

最新状态:

2014-06-07:最新版已经修正了ip认证部分


漏洞评价:

评论