Joomla!是世界上最受欢迎的内容管理系统(CMS)解决方案之一。它可以让用户自定义构建网站实现强大的在线应用程序。

在Joomla!3.7.0版本中新引入了一个组件“com_fields”,这个组件任何人都可以访问,无需登陆验证。但是由于程序员设计缺陷,从这个组建中导入了同名的后台管理员组件,而正好在这个后台的同名组建中由于对用户输入过滤不严格,导致严重SQL注入漏洞。

漏洞分析

首先看看前台的这个组件com_fields, \Joomla_3.7.0\components\com_fields目录,controller.php文件:

这里我们可以看到当我们的参数view=fields,layout=modal时,

url=http://localhost/index.php?option=com_fields&view=fields&layout=modal

此时设置$config[‘base_path’] = JPATH_COMPONENT_ADMINISTRATOR;

设置为管理后的组件路径: \Joomla_3.7.0\administrator\components\

跟进parent::__construct($config)

文件\Joomla_3.7.0\libraries\legacy\controller\legacy.php

这里先获取base_path的值,然后在加载这个路径的模块。

然后进入\Joomla_3.7.0\components\com_fields\fields.php文件

进入execute函数,文件\Joomla_3.7.0\libraries\legacy\controller\legacy.php跟进:

这里的task的值你可以为display,或者你可以不设置task也可以,因为默认

$this->taskMap[‘__default’]的值就是display。

最后return $this->$doTask()就等于return $this->display();

这里的$viewName是取自于view,也就是fields,然后这里先调用getView函数取得视图,然后再调用了getModel获取对应的模型,返回一个model对象,接着再调用setModel函数将获取的model模型push到前面获取的view中去。

最后调用前面获取的view视图的display函数。

文件\Joomla_3.7.0\administrator\components\com_fields\views\fields\view.html.php

第一步,跟进这里的get(‘State’),文件\Joomla_3.7.0\libraries\legacy\view\legacy.php

这里我们的$property是我们传进的实参也就是’State’,那么拼接起来后的方法名$method就是getState方法,然后调用这个方法。

getState方法在文件\Joomla_3.7.0\libraries\legacy\model\legacy.php中

然后调用populateState方法,文件

\Joomla_3.7.0\administrator\components\com_fields\models\fields.php

在populateState方法中调用了父类的populateState方法,跟进

文件\Joomla_3.7.0\libraries\legacy\model\list.php

从代码中可以看到,这里首先获取用户的输入内容赋值给list,然后变量list,然后当name等于fullordering的时候就对list[name]对应的value进行处理,这里对value进行了两次判断,如果条件成立就设置setState,但是这里两个条件都不成立,到最后统一来一次setState,问题就出在这里了,虽然前面各种判断有异常,但是到之后还是统一进行了setState。

第二步,跟进这里的get(‘Items’),文件\Joomla_3.7.0\libraries\legacy\model\list.php

这里调用了当前类的_getListQuery函数

然后又调用当前类的getListQuery方法

先获取我们输入的list.fullordering,也就是list[fullordering]的值,然后通过escape处理,再通过order构造返回要query。

Escape也就是通过函数mysqli_real_escape_string简单处理。

看看order干了什么,文件\Joomla_3.7.0\libraries\joomla\database\query.php

可以看到也就是简单的赋值过程,没有什么过滤处理。

所以上面的过程,我们输入的list[fullordering]的值就成功到这里的query了,最后被sql执行,导致sql注入漏洞。

最后query的值如下图:

漏洞利用

简单的程序验证:

http://10.65.20.198/Joomla_3.7.0/index.php?option=com_fields&view=fields&layout=modal &filter[search]=123&list[fullordering]=updatexml(0x3a,concat(1,(select%20md5(1))),1)

这里GET请求或者POST请求都可以

http://10.65.20.198/Joomla_3.7.0/index.php?option=com_fields&view=fields&layout=modal

漏洞修复

看看补丁的修复过程,如下图:

在文件\Joomla_3.7.0\libraries\legacy\model\list.php中,处理fullordering的时候,当不满足条件时,添加else条件处理过程,使用系统默认的值进行查询。

升级最新版完整安装包以及升级补丁包

https://downloads.joomla.org/cms/joomla3/3-7-1

参考链接

https://blog.sucuri.net/2017/05/sql-injection-vulnerability-joomla-3-7.html

http://bobao.360.cn/learning/detail/3868.html

如果您需要了解更多内容,可以
加入QQ群:570982169
直接询问:010-68438880

 

源链接

Hacking more

...