### 漏洞相关文件 #### 1. /ajax.php ``` if($_REQUEST['act']=='count_buy_total') { require_once APP_ROOT_PATH."system/libs/cart.php"; $region_id = intval($_REQUEST['region_id']); //配送地区 $delivery_id = intval($_REQUEST['delivery_id']); //配送方式 $account_money = floatval($_REQUEST['account_money']); //余额 $ecvsn = $_REQUEST['ecvsn']?$_REQUEST['ecvsn']:''; $ecvpassword = $_REQUEST['ecvpassword']?$_REQUEST['ecvpassword']:''; $payment = intval($_REQUEST['payment']); $all_account_money = intval($_REQUEST['all_account_money']); $user_id = intval($GLOBALS['user_info']['id']); $session_id = session_id(); $goods_list = $GLOBALS['db']->getAll("select * from ".DB_PREFIX."deal_cart where session_id='".$session_id."' and user_id=".$user_id); $result = count_buy_total($region_id,$delivery_id,$payment,$account_money,$all_account_money,$ecvsn,$ecvpassword,$goods_list); $GLOBALS['tmpl']->assign("result",$result); $html = $GLOBALS['tmpl']->fetch("inc/cart/cart_total.html"); $data = $result; $data['html'] =...
### 漏洞相关文件 #### 1. /ajax.php ``` if($_REQUEST['act']=='count_buy_total') { require_once APP_ROOT_PATH."system/libs/cart.php"; $region_id = intval($_REQUEST['region_id']); //配送地区 $delivery_id = intval($_REQUEST['delivery_id']); //配送方式 $account_money = floatval($_REQUEST['account_money']); //余额 $ecvsn = $_REQUEST['ecvsn']?$_REQUEST['ecvsn']:''; $ecvpassword = $_REQUEST['ecvpassword']?$_REQUEST['ecvpassword']:''; $payment = intval($_REQUEST['payment']); $all_account_money = intval($_REQUEST['all_account_money']); $user_id = intval($GLOBALS['user_info']['id']); $session_id = session_id(); $goods_list = $GLOBALS['db']->getAll("select * from ".DB_PREFIX."deal_cart where session_id='".$session_id."' and user_id=".$user_id); $result = count_buy_total($region_id,$delivery_id,$payment,$account_money,$all_account_money,$ecvsn,$ecvpassword,$goods_list); $GLOBALS['tmpl']->assign("result",$result); $html = $GLOBALS['tmpl']->fetch("inc/cart/cart_total.html"); $data = $result; $data['html'] = $html; ajax_return($data); } ``` 文件中红色处看到ecvsn变量和 ecvpassword 变量均是外部获取的,表示可控。而后带入了count_buy_total 函数中,count_buy_total函数的定义在: #### 2. \system\libs\cart.php ``` function count_buy_total($region_id,$delivery_id,$payment,$account_money,$all_account_money,$ecvsn,$ecvpassword,$goods_list,$paid_account_money = 0,$paid_ecv_money = 0) { //获取商品总价 //计算运费 $pay_price = 0; //支付总价 $total_price = 0; $total_weight = 0; $return_total_score = 0; $return_total_money = 0; $is_delivery = 0; foreach($goods_list as $k=>$v) { $total_price += $v['total_price']; $deal_info = $GLOBALS['db']->getRow("select * from ".DB_PREFIX."deal where id = ".$v['deal_id']); if($deal_info['is_delivery'] == 1) //需要配送叠加重量 { $deal_weight = floatval($deal_info['weight']); //团购商品的单位重量 $deal_weight_unit = $GLOBALS['db']->getRowCached("select * from ".DB_PREFIX."weight_unit where id = ".$deal_info['weight_id']); //团购的重单单价 $deal_weight = $deal_weight * $deal_weight_unit['rate']; //转换为为1的重量 $total_weight += ($deal_weight*$v['number']); $is_delivery = 1; } $return_total_money = $return_total_money + $deal_info['return_money'] * $v['number']; $return_total_score = $return_total_score + $deal_info['return_score'] * $v['number']; } $region_info = $GLOBALS['db']->getRowCached("select * from ".DB_PREFIX."delivery_region where id = ".intval($region_id)); $delivery_info = $GLOBALS['db']->getRowCached("select * from ".DB_PREFIX."delivery where id = ".intval($delivery_id)); $delivery_fee = count_delivery_fee($total_weight,$region_id, intval($delivery_info['id'])); $pay_price = $total_price + $delivery_fee; //加上运费 $pay_price = $pay_price - $paid_account_money - $paid_ecv_money; //先计算用户等级折扣 $user_id = intval($GLOBALS['user_info']['id']); $group_info = $GLOBALS['db']->getRow("select g.* from ".DB_PREFIX."user as u left join ".DB_PREFIX."user_group as g on u.group_id = g.id where u.id = ".$user_id); if($group_info&&$total_price>0) $user_discount = $total_price * (1-floatval($group_info['discount'])); else $user_discount = 0; $pay_price = $pay_price - $user_discount; //扣除用户折扣 //余额支付 $user_money = $GLOBALS['db']->getOne("select money from ".DB_PREFIX."user where id = ".$user_id); if($all_account_money == 1) { $account_money = $user_money; } if($account_money>$user_money) $account_money = $user_money; //余额支付量不能超过帐户余额 //开始计算代金券 $now = get_gmtime(); $ecv_sql = "select e.* from ".DB_PREFIX."ecv as e left join ". DB_PREFIX."ecv_type as et on e.ecv_type_id = et.id where e.sn = '". $ecvsn."' and e.password = '". $ecvpassword."' and ((e.begin_time <> 0 and e.begin_time < ".$now.") or e.begin_time = 0) and ". "((e.end_time <> 0 and e.end_time > ".$now.") or e.end_time = 0) and ((e.use_limit <> 0 and e.use_limit > e.use_count) or (e.use_limit = 0)) ". "and (e.user_id = ".$user_id." or e.user_id = 0)"; $ecv_data = $GLOBALS['db']->getRow($ecv_sql); $ecv_money = $ecv_data['money']; ``` 在最后处看到ecv_sql的语句包含了之前的ecvsn变量,且没有经过任何过滤,之后就带入了数据库进行取值,直接导致了SQL注入漏洞。