搜索
查看: 5669|回复: 0

phpshe注入漏洞(目测通杀)

[复制链接]

45

主题

26

回帖

166

积分

注册会员

积分
166

注册会员活跃会员

发表于 2018-3-7 19:47:44 | 显示全部楼层 |阅读模式 来自 甘肃陇南
起因文件include\plugin\payway\alipay\return_url_db.php:这是一个付款的调用文件
  1. $alipayNotify = new AlipayNotify($alipay_config);
  2. $verify_result = $alipayNotify->verifyReturn();
  3. //验证成功
  4. if ($verify_result) {
  5.         //商户订单号
  6.         $out_trade_no = $_GET['out_trade_no'];
  7.         echo $out_trade_no;
  8.         //支付宝交易号
  9.         $trade_no = $_GET['trade_no'];
  10.         $info = $db->pe_select('order', array('order_id'=>$out_trade_no));
  11.     if ($_GET['trade_status'] == 'WAIT_SELLER_SEND_GOODS') {
  12.                 if ($info['order_state'] == 'notpay') {
  13.                         $order['order_outid'] = $trade_no;
  14.                         $order['order_payway'] = 'alipay_db';
  15.                         $order['order_state'] = 'paid';
  16.                         $order['order_ptime'] = time();                                       
  17.                         $db->pe_update('order', array('order_id'=>$out_trade_no), $order);
  18.                 }
  19. 一般我会先去证明漏洞是否存在然后再看上面的验证条件(首先这里肯定不是必须管理员情况下才能够利用),这里用了最简单的GET获取直接带入pe_select(跟人)

  20. public function pe_select($table, $where = '', $field = '*')
  21. {
  22.         //处理条件语句
  23.         $sqlwhere = $this->_dowhere($where);
  24.         return $this->sql_select("select {$field} from `".dbpre."{$table}` {$sqlwhere} limit 1");
  25. }
  26. 继续跟进_dowhere

  27. protected function _dowhere($where)
  28.         {
  29.                 if (is_array($where)) {
  30.                         foreach ($where as $k => $v) {
  31.                                 $k = str_ireplace('`', '', $k);
  32.                                 if (is_array($v)) {
  33.                                         $where_arr[] = "`{$k}` in('".implode("','", $v)."')";                        
  34.                                 }
  35.                                 else {
  36.                                         in_array($k, array('order by', 'group by')) ? ($sqlby = " {$k} {$v}") : ($where_arr[] = "`{$k}` = '{$v}'");
  37.                                 }
  38.                         }
  39.                         $sqlwhere = is_array($where_arr) ? 'where '.implode($where_arr, ' and ').$sqlby : $sqlby;
  40.                 }
  41.                 else {
  42.                         $where && $sqlwhere = (stripos(trim($where), 'order by') === 0 or stripos(trim($where), 'group by') === 0) ? "{$where}" : "where 1 {$where}";
  43.                 }
  44.                 return $sqlwhere;
  45.         }
  46. 可以看到这里面并没有应用到安全函数,只是对内容进行一些简单的链接,分割等操作

  47. public function sql_select($sql)
  48.         {
  49.                 $row = array();
  50.                 return $row = $this->fetch_assoc($this->query($sql));
  51.         }
  52. 而在sql_select函数中就直接执行查询了,所以可以肯定漏洞存在,那么现在就是绕过上面的判断
  53. 跟进verifyReturn看看
  54. 判断文件:/include/plugin/payway/alipay/lib/alipay_notify.class.php

  55. function verifyReturn(){
  56.                if(empty($_GET)) {//判断POST来的数组是否为空
  57.                        return false;
  58.                }
  59.                else {
  60.                        //生成签名结果
  61.                        $isSign = $this->getSignVeryfy($_GET, $_GET["sign"]);
  62.                        //获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
  63.                        $responseTxt = 'true';
  64.                        if (! empty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);}
  65.                         
  66.                        //写日志记录
  67.                        //if ($isSign) {
  68.                        //        $isSignStr = 'true';
  69.                        //}
  70.                        //else {
  71.                        //        $isSignStr = 'false';
  72.                        //}
  73.                        //$log_text = "responseTxt=".$responseTxt."\n return_url_log:isSign=".$isSignStr.",";
  74.                        //$log_text = $log_text.createLinkString($_GET);
  75.                        //logResult($log_text);
  76.                         
  77.                        //验证
  78.                        //$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
  79.                        //isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
  80.                        if (preg_match("/true$/i",$responseTxt) && $isSign) {
  81.                                return true;
  82.                        } else {
  83.                                return false;
  84.                        }
  85.                }
  86.        }
  87. 函数开始先判断GET是否为空,我们跟入看看

  88. function getSignVeryfy($para_temp, $sign) {
  89.                 //除去待签名参数数组中的空值和签名参数
  90.                 $para_filter = paraFilter($para_temp);
  91.                  
  92.                 //对待签名参数数组排序
  93.                 $para_sort = argSort($para_filter);
  94.                  
  95.                 //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
  96.                 $prestr = createLinkstring($para_sort);
  97.                 $isSgin = false;
  98.                 switch (strtoupper(trim($this->alipay_config['sign_type']))) {
  99.                         case "MD5" :
  100.                                 $isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']);
  101.                                 break;
  102.                         default :
  103.                                 $isSgin = false;
  104.                 }
  105.                  
  106.                 return $isSgin;
  107.         }
复制代码
前面三个函数都是对我们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 唉 这也同时造成这个漏洞鸡肋的唯一点
漏洞复现:

第二枚就简单实在好利用:
漏洞文件:include\plugin\payway\ebank\Receive.php
<?phpinclude('../../../../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>
个性
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表