Joomla 3.4.6 RCE 漏洞分析,首发先知社区: https://xz.aliyun.com/t/6522
session 在 Joomla 中的处理有一些的问题,它会把没有通过验证的用户名和密码存储在 _session 表中

在登陆过程中,会有一个 303 的跳转,这个 303 是先把用户的输入存在数据库中,再从数据库中读取、对比,即先执行 write 函数在执行 read 函数

而且它的 csrf token 也在前端页面中

这两个函数位于 libraries/joomla/session/storage/database.php 中,内容如下:

可以看到,它在写入的过程中将 \x00*\x00 替换为 \0\0\0 ,因为 MySQL 中不能存储 NULL ,而 protected 变量序列化后带有 \x00*\x00
在读取过程中会重新把 \0\0\0 替换为 \x00*\x00 以便反序列化,但是这个替换将 3 字节的内容替换为 6 字节
如果提交的 username 为 per\0\0\0i0d ,那么在 read 时返回的数据就是 s:8:s:"username";s:12:"perNNNi0d" N 代表 NULL,替换的大小为 9 字节,但是声明的是 12 字节,那么这将是一个无效的对象
那么就可以利用这个溢出来构造"特殊"的代码
值得一提的是,在进行 replace 后,反序列化时 username 会按照 54 的长度读取,读取到 password 字段处,以其结尾的 ; 作为结尾,而 password 字段的内容就逃逸出来,直接进行反序列化了。
思路
\0\0\0 溢出,来逃逸密码 value在数据库中
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:6:"123456"在读取置换之后
s:8:s:"username";s:54:"NNNNNNNNNNNNNNNNNNNNNNNNNNN";s:8:"password";s:6:"123456"实现对象注入
s:8:s:"username";s:54:"NNNNNNNNNNNNNNNNNNNNNNNNNNN";s:8:"password";s:6:"1234";s:2:"HS":O:15:"ObjectInjection"接下来就是 POP 链的构造
在 libraries/joomla/database/driver/mysqli.php 中的 __destruct() 触发 disconnect() 函数,对 disconnectHandlers 数组中的每个值,都会执行 call_user_func_array() ,并将 &$this 作为参数引用,但是不能控制参数,利用条件是 $this->connection 为 true
public function __destruct()
{
$this->disconnect();
}
public function disconnect()
{
// Close the connection.
if ($this->connection)
{
foreach ($this->disconnectHandlers as $h)
{
call_user_func_array($h, array( &$this));
}
mysqli_close($this->connection);
}
$this->connection = null;
}但是在 libraries/simplepie/simplepie.php 中又有可以利用的,这里的函数和参数值都在我们的控制之下

这条语句执行的条件是 $this->cache 必须为 true ,$parsed_feed_url[‘scheme‘] 不为空
根据这些信息就能够构造出反序列化链了,如下图,可以很清晰看出构造方式

如果 zopatkgieeqqmifstiih 出现在返回页面就可以判断存在该漏洞
原文:https://www.cnblogs.com/peri0d/p/11670364.html