学习了,感谢,测试了一下帐号用/d/w*的方式也可以登录对应的id
前面的登录思路是来源于——Joseph
后面的组合扩大攻击来源于——zxc
简述
Dedecms是一款开源的PHP开源网站管理系统。
DeDecms(织梦CMS) V5.7.72 正式版20180109 (最新版)
前台会员模块是采用Cookie中的 DedeUserID+DedeUserID__ckMd5字段进行身份鉴别
DedeUserID用于定位区别用户,DedeUserID__ckMd5则是服务器生成散列,用于安全验证
Dedecms一处代码由于逻辑不够严谨,导致可以输入字符并获得服务器生成散列
劫持DedeUserID__ckMd5字段,绕过安全校验,配合类型转换造成任意用户登录漏洞
漏洞详细原理
文件位置:dedecms/member/index.php:110行
require_once(DEDEMEMBER . '/inc/config_space.php');
if ($action == '') {
include_once(DEDEINC . "/channelunit.func.php");
$dpl = new DedeTemplate();
$tplfile = DEDEMEMBER . "/space/{$_vars['spacestyle']}/index.htm";
//更新最近访客记录及站点统计记录
$vtime = time();
$last_vtime = GetCookie('last_vtime');
$last_vid = GetCookie('last_vid');
if (empty($last_vtime)) {
$last_vtime = 0;
}
if ($vtime - $last_vtime > 3600 || !preg_match('#,' . $uid . ',#i', ',' . $last_vid . ',')) {
if ($last_vid != '') {
$last_vids = explode(',', $last_vid);
$i = 0;
$last_vid = $uid;
foreach ($last_vids as $lsid) {
if ($i > 10) {
break;
} else if ($lsid != $uid) {
$i++;
$last_vid .= ',' . $last_vid;
}
}
} else {
$last_vid = $uid;
}
PutCookie('last_vtime', $vtime, 3600 * 24, '/');
PutCookie('last_vid', $last_vid, 3600 * 24, '/');
这段函数中$uid是我们可控的,如果Cookie中last_vid字段不存在就会走进这个分支
} else {
$last_vid = $uid;
}
也就变为$last_vid
可控,然后$last_vid
经过PutCookie
函数进行处理
顺便一提
文件位置:dedecms/include/helpers/cookie.helper.php
PutCookie这个函数是Dedecms在setcookie时封装的函数
GetCookie这个函数是Dedecms在获取Cookie中值封装的函数
如果Set一个键值对,PutCookie会Set两对Cookie,一个是要SET的键值对
另一个是值和key进行md5的哈希再截取前十六位的安全校验字符串(键名为$key+'__ckMd5'
)
if ( ! function_exists('PutCookie'))
{
function PutCookie($key, $value, $kptime=0, $pa="/")
{
global $cfg_cookie_encode,$cfg_domain_cookie;
setcookie($key, $value, time()+$kptime, $pa,$cfg_domain_cookie);
setcookie($key.'__ckMd5', substr(md5($cfg_cookie_encode.$value),0,16), time()+$kptime, $pa,$cfg_domain_cookie);
}
}
GetCookie在返回键值之前,会通过PutCookie生成的十六位安全校验字符串对键值进行安全校验
确保获得的键值对有效且为服务器Set,增强安全性(但这里并不能抵御密文重放)
if ( ! function_exists('GetCookie'))
{
function GetCookie($key)
{
global $cfg_cookie_encode;
if( !isset($_COOKIE[$key]) || !isset($_COOKIE[$key.'__ckMd5']) )
{
return '';
}
else
{
if($_COOKIE[$key.'__ckMd5']!=substr(md5($cfg_cookie_encode.$_COOKIE[$key]),0,16))
{
return '';
}
else
{
return $_COOKIE[$key];
}
}
}
}
点击收藏 | 0
关注 | 3