phpshe注入漏洞(目测通杀)

  • A+
所属分类:漏洞时代
摘要

起因文件include/plugin/payway/alipay/return_url_db.php:这是一个付款的调用文件一般我会先去证明漏洞是否存在然后再看上面的验证条件(首先这里肯定不是必须管理员情况下才能够利用),这里用了最简单的GET获取直接带入pe_select(跟人)

起因文件include/plugin/payway/alipay/return_url_db.php:这是一个付款的调用文件

$alipayNotify = new AlipayNotify($alipay_config); $verify_result = $alipayNotify->verifyReturn(); //验证成功 if ($verify_result) {         //商户订单号         $out_trade_no = $_GET['out_trade_no'];         echo $out_trade_no;         //支付宝交易号         $trade_no = $_GET['trade_no'];         $info = $db->pe_select('order', array('order_id'=>$out_trade_no));     if ($_GET['trade_status'] == 'WAIT_SELLER_SEND_GOODS') {                 if ($info['order_state'] == 'notpay') {                         $order['order_outid'] = $trade_no;                         $order['order_payway'] = 'alipay_db';                         $order['order_state'] = 'paid';                         $order['order_ptime'] = time();                                                                 $db->pe_update('order', array('order_id'=>$out_trade_no), $order);                 }

一般我会先去证明漏洞是否存在然后再看上面的验证条件(首先这里肯定不是必须管理员情况下才能够利用),这里用了最简单的GET获取直接带入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"); }

继续跟进_dowhere

protected function _dowhere($where)         {                 if (is_array($where)) {                         foreach ($where as $k => $v) {                                 $k = str_ireplace('`', '', $k);                                 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;         }

可以看到这里面并没有应用到安全函数,只是对内容进行一些简单的链接,分割等操作

public function sql_select($sql)         {                 $row = array();                 return $row = $this->fetch_assoc($this->query($sql));         }

而在sql_select函数中就直接执行查询了,所以可以肯定漏洞存在,那么现在就是绕过上面的判断
跟进verifyReturn看看
判断文件:/include/plugin/payway/alipay/lib/alipay_notify.class.php

 function verifyReturn(){                if(empty($_GET)) {//判断POST来的数组是否为空                        return false;                }                else {                        //生成签名结果                        $isSign = $this->getSignVeryfy($_GET, $_GET["sign"]);                        //获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)                        $responseTxt = 'true';                        if (! empty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);}                                                 //写日志记录                        //if ($isSign) {                        //        $isSignStr = 'true';                        //}                        //else {                        //        $isSignStr = 'false';                        //}                        //$log_text = "responseTxt=".$responseTxt."/n return_url_log:isSign=".$isSignStr.",";                        //$log_text = $log_text.createLinkString($_GET);                        //logResult($log_text);                                                 //验证                        //$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关                        //isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关                        if (preg_match("/true$/i",$responseTxt) && $isSign) {                                return true;                        } else {                                return false;                        }                }        }

函数开始先判断GET是否为空,我们跟入看看

function getSignVeryfy($para_temp, $sign) {                 //除去待签名参数数组中的空值和签名参数                 $para_filter = paraFilter($para_temp);                                   //对待签名参数数组排序                 $para_sort = argSort($para_filter);                                   //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串                 $prestr = createLinkstring($para_sort);                 $isSgin = false;                 switch (strtoupper(trim($this->alipay_config['sign_type']))) {                         case "MD5" :                                 $isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']);                                 break;                         default :                                 $isSgin = false;                 }                                   return $isSgin;         }

前面三个函数都是对我们GET进来的数组进行整理与链接的操作
这里的三个变量,有两个变量是我们可控的,而$this->alipay_config['key'] 是我们在支付宝中的接口key值是无法控的
而我们跟进md5Verify

function md5Verify($prestr, $sign, $key) {         $prestr = $prestr . $key;         $mysgin = md5($prestr);         if($mysgin == $sign) {                 return true;         }         else {                 return false;         } }

果然与书上写的一样,o(︶︿︶)o 唉 这也同时造成这个漏洞鸡肋的唯一点
漏洞复现:
phpshe注入漏洞(目测通杀)

第二枚就简单实在好利用:

漏洞文件:include/plugin/payway/ebank/Receive.php

<?php include('../../../../common.php'); $cache_payway = cache::get('payway'); $payway = unserialize($cache_payway['ebank']['payway_config']); $key   = $payway['ebank_md5'];   $v_oid     =trim($_POST['v_oid']); $v_pmode   =trim($_POST['v_pmode']); $v_pstatus =trim($_POST['v_pstatus']); $v_pstring =trim($_POST['v_pstring']); $v_amount  =trim($_POST['v_amount']); $v_moneytype  =trim($_POST['v_moneytype']); $remark1   =trim($_POST['remark1']); $remark2   =trim($_POST['remark2']); $v_md5str  =trim($_POST['v_md5str']);   /**  * 重新计算md5的值  */   $md5string=strtoupper(md5($v_oid.$v_pstatus.$v_amount.$v_moneytype.$key)); echo $key;   /**  * 判断返回信息,如果支付成功,并且支付结果可信,则做进一步的处理  */   if ($v_md5str==$md5string) {         if($v_pstatus=="20") {                 $info = $db->pe_select('order', array('order_id'=>$v_oid));                 if ($info['order_state'] == 'notpay') {                         $order['order_outid'] = $v_pmode;                         $order['order_payway'] = 'ebank';                         $order['order_state'] = 'paid';                         $order['order_ptime'] = time();                         $db->pe_update('order', array('order_id'=>$v_oid), $order);                         pe_success('订单支付成功...');                 }         }         else {                 echo "支付失败";         } } else{         echo "<br>校验失败,数据可疑"; } ?> </BODY> </HTML>

这里看似与第一个一样,其实并不一样,这里的ebank是代表的一种支付方式,而咱们一般网站采用大部分都是支付宝,所以当我们没有调用这种支付方式的时候此值为空
自然这里的链接也变成了:md5($v_oid.$v_pstatus.$v_amount.$v_moneytype)
phpshe注入漏洞(目测通杀)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: