@phpice 后台再次编辑有问题,先把你的回复用我的账号发,晚点给你恢复过来
我在16年的时候也以为是一个前台的漏洞,并提交给了先知,被驳回了,再后来我仔细测试后发现其实这是一个后台漏洞。
如果不仔细读代码确实很容易被误导。
你能在本地测试成功是因为你先登录了后台,此时已经存在了一个登录后台成功的session,然后再没用注销登录的情况下直接访问member目录,这个时候前台自动登录了admin账号,然后你想注册一个新会员,嗯,然后你前台注销登录。此时看起来好像没有任何问题,但就是这个操作让我们都以为注销成功了,其实并没有,这个时候只是注销了前台的登录,并没有注销后台的登录,回过头来,我们继续注册会员,登录会员,这个时候的所有操作都是基于前面那个登录后台成功的session进行的。贴一段代码
//检验用户登录状态
$cuserLogin = new userLogin();
if($cuserLogin->getUserID() <=0 )
{
if(empty($adminDirHand))
{
ShowMsg("提示:需输入后台管理目录才能登录
请输入后台管理目录名:", "javascript:;");exit();
}
$adminDirHand = HtmlReplace($adminDirHand, 1);
$gurl = "../../{$adminDirHand}/login.php?gotopage=".urlencode($dedeNowurl);
echo "";
exit();
}
class userLogin
{
var $userName = '';
var $userPwd = '';
var $userID = '';
var $adminDir = '';
var $userType = '';
var $userChannel = '';
var $userPurview = '';
var $keepUserIDTag = 'dede_admin_id';
var $keepUserTypeTag = 'dede_admin_type';
var $keepUserChannelTag = 'dede_admin_channel';
var $keepUserNameTag = 'dede_admin_name';
var $keepUserPurviewTag = 'dede_admin_purview';
var $keepAdminStyleTag = 'dede_admin_style';
var $adminStyle = 'dedecms';
//php5构造函数
function __construct($admindir='')
{
global $admin_path;
if(isset($_SESSION[$this->keepUserIDTag]))
{
$this->userID = $_SESSION[$this->keepUserIDTag];
$this->userType = $_SESSION[$this->keepUserTypeTag];
$this->userChannel = $_SESSION[$this->keepUserChannelTag];
$this->userName = $_SESSION[$this->keepUserNameTag];
$this->userPurview = $_SESSION[$this->keepUserPurviewTag];
$this->adminStyle = $_SESSION[$this->keepAdminStyleTag];
}
if($admindir!='')
{
$this->adminDir = $admindir;
}
else
{
$this->adminDir = $admin_path;
}
}
/*
........
*/
function getUserID()
{
if($this->userID != '')
{
return $this->userID;
}
else
{
return -1;
}
}
通过代码可以发现 $this->userid必须不能等于空,$this->userid就是$_SESSION[$this->keepUserIDTag]
也就是$_SESSION['dede_admin_id'];
我们看看$_SESSION['dede_admin_id']是在什么情况下会被赋值
function keepUser()
{
if($this->userID != '' && $this->userType != '')
{
global $admincachefile,$adminstyle;
if(empty($adminstyle)) $adminstyle = 'dedecms';
@session_register($this->keepUserIDTag);
$_SESSION[$this->keepUserIDTag] = $this->userID;
@session_register($this->keepUserTypeTag);
$_SESSION[$this->keepUserTypeTag] = $this->userType;
@session_register($this->keepUserChannelTag);
$_SESSION[$this->keepUserChannelTag] = $this->userChannel;
@session_register($this->keepUserNameTag);
$_SESSION[$this->keepUserNameTag] = $this->userName;
@session_register($this->keepUserPurviewTag);
$_SESSION[$this->keepUserPurviewTag] = $this->userPurview;
@session_register($this->keepAdminStyleTag);
$_SESSION[$this->keepAdminStyleTag] = $adminstyle;
PutCookie('DedeUserID', $this->userID, 3600 * 24, '/');
PutCookie('DedeLoginTime', time(), 3600 * 24, '/');
$this->ReWriteAdminChannel();
return 1;
}
else
{
return -1;
}
}
在看看keepUser 是什么时候被调用的。
//登录检测
$admindirs = explode('/',str_replace("\\",'/',dirname(__FILE__)));
$admindir = $admindirs[count($admindirs)-1];
if($dopost=='login')
{
$validate = empty($validate) ? '' : strtolower(trim($validate));
$svali = strtolower(GetCkVdValue());
if(($validate=='' || $validate != $svali) && preg_match("/6/",$safe_gdopen)){
ResetVdValue();
ShowMsg('验证码不正确!','login.php',0,1000);
exit;
} else {
$cuserLogin = new userLogin($admindir);
if(!empty($userid) && !empty($pwd))
{
$res = $cuserLogin->checkUser($userid,$pwd);
//success
if($res==1)
{
$cuserLogin->keepUser();
if(!empty($gotopage))
{
ShowMsg('成功登录,正在转向管理管理主页!',$gotopage);
exit();
}
else
{
ShowMsg('成功登录,正在转向管理管理主页!',"index.php");
exit();
}
}
//error
else if($res==-1)
{
ResetVdValue();
ShowMsg('你的用户名不存在!','login.php',0,1000);
exit;
}
else
{
ResetVdValue();
ShowMsg('你的密码错误!','login.php',0,1000);
exit;
}
}
//password empty
else
{
ResetVdValue();
ShowMsg('用户和密码没填写完整!','login.php',0,1000);
exit;
}
}
}
只有在后台登录的时候被调用。前台压根就没办法对session进行操作,没有办法控制session就没有办法绕过这个if($cuserLogin->getUserID() <=0 )判断,所以,这是一个假漏洞。
========================================================================
抛开认证问题,就上传绕过来说,同目录下的select_soft_post.php文件更好绕过
把上传文件名改成1.htm.php?
文件类型只要有text就行