### 简要描述: 继续注入。 ### 详细说明: 在lib\plugins\pay\alipay.php中。 上次提了这个文件的洞。 看了看官网发的补丁。 ``` foreach($_POST as $key =>$data) { if(preg_match('/(=|<|>)/', $data)){ return false; } ``` 就是过滤了几个运算符。 但是因为语句是 where xxx。 一般的注入的话 需要where id=xxx 来注入 但是这里过滤了这些。 没想出什么办法突破。 但是在这文件 还有一个函数。 ``` $payment = pay::get_payment($_GET['code']); $seller_email = rawurldecode($_GET['seller_email']); $order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']); $order_sn = trim($order_sn); if (!pay::check_money($order_sn,$_GET['total_fee'])) { return false; } if($_GET['trade_status'] == "WAIT_SELLER_SEND_GOODS"||$_GET['trade_status'] == "TRADE_FINISHED" || $_GET['trade_status'] == "TRADE_SUCCESS") { pay::changeorders($order_sn,$_GET); return true; }else { return false; } ``` 上次是看的changeorders 现在 反正我是没办法利用了。 那现在来看看check_money ``` public static function check_money($id,$money) { $where=array(); $where['id']=$id; $orders=orders::getInstance()->getrow($where);...
### 简要描述: 继续注入。 ### 详细说明: 在lib\plugins\pay\alipay.php中。 上次提了这个文件的洞。 看了看官网发的补丁。 ``` foreach($_POST as $key =>$data) { if(preg_match('/(=|<|>)/', $data)){ return false; } ``` 就是过滤了几个运算符。 但是因为语句是 where xxx。 一般的注入的话 需要where id=xxx 来注入 但是这里过滤了这些。 没想出什么办法突破。 但是在这文件 还有一个函数。 ``` $payment = pay::get_payment($_GET['code']); $seller_email = rawurldecode($_GET['seller_email']); $order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']); $order_sn = trim($order_sn); if (!pay::check_money($order_sn,$_GET['total_fee'])) { return false; } if($_GET['trade_status'] == "WAIT_SELLER_SEND_GOODS"||$_GET['trade_status'] == "TRADE_FINISHED" || $_GET['trade_status'] == "TRADE_SUCCESS") { pay::changeorders($order_sn,$_GET); return true; }else { return false; } ``` 上次是看的changeorders 现在 反正我是没办法利用了。 那现在来看看check_money ``` public static function check_money($id,$money) { $where=array(); $where['id']=$id; $orders=orders::getInstance()->getrow($where); $archive=archive::getInstance()->getrow($orders['aid']); $prices = getPrices($archive['attr2']); $archive['attr2'] = $prices['price']; ``` 可以看到是把order_sn 带入了getrow; 再继续 ``` function getrow($condition,$order='1 desc',$cols='*') { $this->condition($condition); return $this->rec_select_one($condition,'*',$order); ``` ``` function sql_select($tbname,$where="",$limit=0,$fields="*",$order='') { $sql="SELECT ".$fields." FROM `".$tbname."` ".($where ?" WHERE ".$where : "")." ORDER BY ".$order.($limit ?" limit ".$limit : ""); //echo $sql." "; return $sql; ``` 这里来把语句输出一下看看。 SELECT * FROM `cmseasy_p_orders` WHERE `id`='123aaaa' 被单引号了。 但是又全局转义 怎么办呢? 看 $order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']); $order_sn = trim($order_sn); 这里跟ecshop 那个洞挺像。 在这里 有一个replace 是xx把清空 但是这个xxx是我们可控的。 总所周知 %00 转义后会变成\0 然后%00' 就是\0\' 这里 如果我们把0清空 的话 就成了\\' 单引号成功出来。 测试测试。 ### 漏洞证明: [<img src="https://images.seebug.org/upload/201403/091424412ddb45476909fe9780eb78e03ae7846a.jpg" alt="cmseasy.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201403/091424412ddb45476909fe9780eb78e03ae7846a.jpg) 执行的语句有点多。。 直接全部输出来了。 是成功的哦。