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

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

缺陷编号:wooyun-2014-068777

漏洞标题:sitestar某功能鸡肋sql(需要一定条件)

相关厂商:建站之星

漏洞作者: D&G

提交时间:2014-07-16 21:49

修复时间:2014-10-14 21:50

公开时间:2014-10-14 21:50

漏洞类型:SQL注射漏洞

危害等级:中

自评Rank:10

漏洞状态:厂商已经修复

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-07-16: 细节已通知厂商并且等待厂商处理中
2014-07-17: 厂商已经确认,细节仅向厂商公开
2014-09-10: 细节向核心白帽子及相关领域专家公开
2014-09-20: 细节向普通白帽子公开
2014-09-30: 细节向实习白帽子公开
2014-10-14: 厂商已经修复漏洞并主动公开,细节向公众公开

简要描述:

sql injection

详细说明:

sitestar没有做全局的数据转义,很容易出现遗漏的地方。
测试版本sitestar_v2.7_build140505
出现问题的地方在module/mod_order.php 176行开始。
鸡肋的地方在于这是一个普通用户使用的积分兑换功能。需要用户最少有100积分才可以之星下面的逻辑。

public function userjifen_save(){
$integral = ParamHolder::get('exchange');
if (trim(SessionHolder::get('SS_LOCALE')) != '') {// 多语言切换用
$curr_locale = trim(SessionHolder::get('_LOCALE'));
} else {
$curr_locale = DEFAULT_LOCALE;
}
$lang_sw = trim(ParamHolder::get('lang_sw', $curr_locale));
SessionHolder::set('mod_site/_LOCALE', $lang_sw);

//读取积分总额:
$curr_user_id = SessionHolder::get('user/id');
$o_user_ext = new UserExtend();
$curr_user_ext =& $o_user_ext->find("user_id=?", array($curr_user_id));
if (!$curr_user_ext) {
$this->assign('json', Toolkit::jsonERR(__('Invalid ID!')));
return '_error';
}

if ($curr_user_ext->total_point < 100 ){
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
echo '<script type="text/javascript">
alert("'.__('Sorry, membership points can be converted more than 100 Member Points').'");
location.href="'.Html::uriquery('mod_order', 'userjifen').'";</script>';
exit;
}
switch ($integral){
case 100:
$cash = 10;
echo $integral;
break;
case 200:
$cash = 20;
break;
case 500:
$cash = 50;
break;
case 1000:
$cash = 100;
break;
default:
$cash = 0;
break;
}
echo $cash;
if ($cash==0) {
$this->assign('json', Toolkit::jsonERR(__('Please select the options you want to exchange')));
echo 'test';
return '_error';
echo 'test';
exit;
}
//加入会员的账户余额:
//读取账户的总额,加上兑换的余额,并更新总额:
$curr_user_ext -> total_saving = $curr_user_ext -> total_saving + $cash;
$curr_user_ext -> balance = $curr_user_ext -> balance +$cash;
$curr_user_ext -> save();
//生成一个交易记录:
$o_transaction = new Transaction();
$o_transaction->action_time = time();
$o_transaction->user_id = $curr_user_id;
$o_transaction->type = '1';
$o_transaction->amount = $cash;
$o_transaction->memo = __('Redeem account balance');
$o_transaction->save();

//记录进积分记录表:
$userPoint = array();
$userPoint['userid'] = $curr_user_id;
$userPoint['type'] = 'out';
$userPoint['point'] = $integral;
$userPoint['momo'] = __('Redeem account balance');
$userPoint['create_time'] = time();
$db =& MySqlConnection::get();
$sql = "insert into ss_users_points(id,userid,orderid,type,point,momo,create_time) values (null,'{$userPoint['userid']}','0','{$userPoint['type']}','{$userPoint['point']}','{$userPoint['momo']}','{$userPoint['create_time']}')";
$db->query($sql);

//清零会员的积分
$curr_user_ext->total_point = $curr_user_ext->total_point-$integral;
$curr_user_ext -> save();


问题参数$integral。这里这样一段逻辑:

switch ($integral){
case 100:
$cash = 10;
echo $integral;
break;
case 200:
$cash = 20;
break;
case 500:
$cash = 50;
break;
case 1000:
$cash = 100;
break;
default:
$cash = 0;
break;
}


看起来像是用白名单的方式限制了$ingegral。其实不然。$integral并没有限制数据类型。这里的一个小trick就是。
当$integral为字符串100asdg时,case 100。结果是true。
可以参考:

如果比较一个整数和字符串,则字符串会被转换为整数。如果比较两个数字字符串,则作为整数比较。此规则也适用于 switch 语句。

<?php
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
switch ("a") {
case 0:
echo "0";
break;
case "a": // never reached because "a" is already matched with 0
echo "a";
break;
}
?>

字符串转换为数值
当一个字符串被当作数字来求值时,根据以下规则来决定结果的类型和值。
如果包括“.”,“e”或“E”其中任何一个字符的话,字符串被当作 float 来求值。否则就被当作整数。
该值由字符串最前面的部分决定。如果字符串以合法的数字数据开始,就用该数字作为其值,否则其值为 0(零)。合法数字数据由可选的正负号开始,后面跟着一个或多个数字(可选地包括十进制分数),后面跟着可选的指数。指数是一个“e”或者“E”后面跟着一个或多个数字。

<?php
$foo = 1 + "10.5"; // $foo is float (11.5)
$foo = 1 + "-1.3e3"; // $foo is float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo is integer (1)
$foo = 1 + "bob3"; // $foo is integer (1)
$foo = 1 + "10 Small Pigs"; // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1; // $foo is float (11)
$foo = "10.0 pigs " + 1.0; // $foo is float (11)
?>


sitestar11.jpg


site.jpg

漏洞证明:

sitestar11.jpg


site.jpg

修复方案:

版权声明:转载请注明来源 D&G@乌云


漏洞回应

厂商回应:

危害等级:低

漏洞Rank:4

确认时间:2014-07-17 20:28

厂商回复:

我们尽快修复,谢谢!

最新状态:

2014-07-18:补丁已经发布,请去官网更新补丁或下载最新安装包,谢谢。