*严正声明:本文仅限于技术讨论与分享,严禁用于非法途径php
10月9号国内几家安全媒体公布了Joomla RCE的漏洞预警,而且网上已公布漏洞利用EXP,影响版本包括Joomla 3.0.0 – 3.4.6。html
Joomla是一套全球知名的内容管理系统。Joomla是使用PHP语言加上MySQL数据库所开发的软件系统,目前最新版本是3.9.11 。能够在Linux、Windows、MacOSX等各类不一样的平台上执行。mysql
Joomla环境搭建下载:https://github.com/joomla/joomla-cms/releases/tag/3.4.6git
PS:搭建环境要求php 5.3.10以上github
PHP自己对Session的存储默认放在文件中,当有会话产生使用到Session时候,将会在网站服务端设置好的路径写入相应的Session文件,文件的内容为默认序列化处理器序列化后的数据。然而在Joomla中则改变了PHP的默认处理规则,相反将序列化以后的数据存放在数据库的” hzlnp_session”表中存储:sql
将序列化以后的数据存放在数据库中所对应的处理函数为由session_set_save_handler()设置的\libraries\joomla\session\storage\database.php 中的write():shell
相应的取值函数read()也位于\libraries\joomla\session\storage\database.php中数据库
接着从代码中能够看出,在存入数据库以前,会将传入数据中的chr(0) . ‘*’ .chr(0) 替换为\0\0\0, 缘由是mysql数据库没法处理NULL字节,而protected 修饰符修饰的字段在序列化以后是以\x00\x2a\x00开头的。而后从数据库中取出来的时候,再将字符进行替换还原,防止没法正常反序列化。安全
session 在 Joomla 中的处理存在一些问题,它会把没有经过验证的用户名和密码存储在hzlnp_session表中session
当用户在登录过程当中,会有一个 303 的跳转,主要是用于write()数据库写入用户会话而后read()相应取出会话进行对比,显示结果
经过分析Session会话机制和Session逃逸咱们还不明确Session造成的漏洞到底在哪!
首先须要了解一下PHP的序列化的机制,PHP在序列化数据的过程当中,若是序列化的字段是一个字符串,那么将会保留该字符串的长度,而后将长度写入到序列化以后的数据,反序列化的时候按照长度进行读取。
知道PHP序列化过程以后,针对Joomla的内置序列化方法write和read函数,若是写入数据库的时候,是\0\0\0, 取出来的时候将会变成chr(0) . ‘*’ . chr(0),这样的话,入库的时候生成的序列化数据长度为6(\0\0\0), 取出来的时候将会成为3(N*N, N表示NULL),依据PHP反序列化原理,该数据在反序列化的时候,若是按照原先的长度进行读取,就会致使溢出。
那么由” \0\0\0”溢出会形成什么问题呢?按照PHP反序列化的特色,PHP按照长度读取指定字段的值,读取完成以分号结束,接着开始下一个,若是咱们可以控制两个字段的值,第一个用来溢出第一个字段和第二个字段的前一部分,第二个字段的另外一部分用来构造序列化利用的payload,最终序列化结果将会把第一个字段开始部分到第二个字段的前一部分当成第一个字段的所有内容,第二个字段内容成功逃逸出来而且被反序列化。
为了触发咱们的任意对象并实现RCE,咱们须要将登陆框处的两个字段username和password进行处理,第一个字段将致使“溢出”,第二个字段将包含漏洞利用的最后一部分。
编写本地测试代码
此处伪代码对Joomla内置的write()、read()函数进行模拟,username字段经过9组”\0\0\0”进行赋值,其值序列化存入数据库db.txt长度为54,反序列化取出长度变为27,加上后面第二个字段password的27个字符构成实际的username值:
O:4:”User”:2:{s:8:”username”;s:57:”xx。。。xxx”;s:8:”password”;s:nn:”payload”;}
因为”;s:8:”password”;s:nn:”长度为23,\0\0\0经read()函数处理以后会减半,因此要想覆盖password字段值,username字段值就要取9组”\0\0\0”,同时password的字段值长度至少须要是两位(nn表明占位符),由于实际上payload的长度会大于10。
测试结果 实现任意对象的注入
首先参考PHITHON 师傅的一篇文章“Joomla远程代码执行漏洞分析“收获不少,依据PHITHON 师傅的思路,一样,在咱们能够控制反序列化对象之后,咱们只需构造一个可以一步步调用的执行链,便可进行一些危险的操做了。exp构造的执行链,分别利用了JDatabaseDriverMysqli和SimplePie类
咱们能够在JDatabaseDriverMysqli类(\libraries\joomla\database\driver\mysqli.php)的析构函数里找到一处敏感操做:
因为exp构造的对象反序列化后,将会成为一个JDatabaseDriverMysqli类对象,无论中间如何执行,最后都将会调用__destruct魔法函数,__destruct将会调用disconnect,disconnect里有一处敏感函数:call_user_func_array。但很遗憾的是,这里的call_user_func_array的第二个参数是咱们没法控制的,可是,咱们能够进行回调利用:
call_user_func_array([$obj,"任意方法"],array( &$this))
进一步跟踪到SimplePie类(\libraries\simplepie\simplepie.php),经过将SimplePie对象和它自己的init()函数能够组成一个回调函数[new SimplePie(), 'init'],传入call_user_func_array
分析init()函数
经过分析代码发现此处的call_user_func 参数可控,只要知足条件$this->cache=true && $parsed_feed_url['scheme'] !== Null,将其中第二个call_user_func的第一个参数cache_name_function赋值为assert,第二个参数赋值为咱们须要执行的代码,这样就能够构成一个可利用的“回调后门“,达到任意代码执行效果。
PS:对于网上爆的利用回调后门在网站根目录下的configuration.php中写入一句话木马getshell这种方式,在真实环境中大多都不能利用成功(权限问题),效果并非太好。
一、版本更新
二、对session信息进行编码存储
https://blog.hacktivesecurity.com/index.php?controller=post&action=view&id_post=41
https://www.leavesongs.com/PENETRATION/joomla-unserialize-code-execute-vulnerability.html
*本文原创做者:Qftmer,本文属于FreeBuf原创奖励计划,未经许可禁止转载
原文出处:https://www.cnblogs.com/qftm/p/11743263.html