潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

admin 2025年6月8日14:26:17评论5 views字数 4363阅读14分32秒阅读模式

漏洞概述

近日官方披露 Roundcube邮件系统中存在一个潜伏了10年之久的严重漏洞,虽然只有认证后才能触发,但CVSS评分仍然高达9.9分。由于Roundcube自定义的session序列化与反序列化函数存在逻辑缺陷,导致可通过构造特殊请求实现RCE。该漏洞影响1.5.101.6.11 以下版本。

补丁对比

补丁地址: https://github.com/roundcube/roundcubemail/commit/0376f69e958a8fef7f6f09e352c541b4e7729c4d 。rcmail_action_settings_upload::run 函数中新增了对请求参数 _from 的格式检查,将其限定为简单字符串类型:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

请求路由分析

首先分析一下到达 rcmail_action_settings_upload::run 的请求路由。 rcmail_action_settings_upload 继承了 rcmail_action 抽象类,分析可知 rcmail_action 子类主要用于处理对应的 HTTP 请求。

在系统首页 index.php中将调用$RCMAIL->action_handler进行路由分发。进入action_handler函数,提取taskaction变量(来自于请求参数_task_action), 并尝试创建处理请求的rcmail_action对象。函数中存在多种类创建方式,比如rcmail_action_{$task}_index,但是显然rcmail_action_settings_upload 满足不了这种格式要求 :

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

往下看还有另一种获取 $class 的方式: rcmail_action_{$task}_{$action} ,如果类存在将调用其 run 函数:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

需要注意在调用 run 之前存在 check 检查:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

可以在请求中加入 _remote 参数,确保 $rcmail->output->ajax_call 非空从而使得 check 函数返回值为 true :

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析
潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

构造如下 HTTP 请求可进入 rcmail_action_settings_upload::run :

GET /?_task=settings&_action=upload&_remote=1&_from=from123...

调用栈如下:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

session序列化与反序列化分析

既然是 PHP反序列化漏洞,首先搜索一下unserialize的调用点。Roundcubeunserialize函数使用的并不多,我们注意到在处理sessionrcube_session类中,自定义了serializeunserialize函数,用于完成session会话的序列化与反序列化。反向搜索rcube_session::unserialize调用点,找到sess_write 函数:

rcube_session.unserialize    │        └─→ rcube_session._fixvars           │              └─→rcube_session.sess_write

直接分析找不到 sess_write的调用点,那么如何触发呢?注意到rcube_session初始化过程中利用session_set_save_handlersess_write注册为了session写入的回调函数,并且类中还定义了appendremovereload等函数对session 进行处理:

public function register_session_handler(){    ...    // set custom functions for PHP session management      session_set_save_handler(          [$this, 'open'],          [$this, 'close'],          [$this, 'read'],          [$this, 'sess_write'],   //设置 sess_write 回调函数        [$this, 'destroy'],          [$this, 'gc']      );    ...}.../** * Re-read session data from storage backend */public function reload().../** * Append the given value to the certain node in the session data array * * Warning: Do not use if you already modified $_SESSION in the same request (#1490608) * * @param string $path  Path denoting the session variable where to append the value * @param string $key   Key name under which to append the new value (use null for appending to an indexed list) * @param mixed  $value Value to append to the session data array */public function append($path, $key, $value).../** * Unset a session variable * * @param string $var Variable name (can be a path denoting a certain node *                    in the session array, e.g. compose.attachments.5) * * @return bool True on success, False on failure */public function remove($var = null)

而 rcmail_action_settings_upload::run 刚好调用了其中的 append 函数。修改请求数据包为图片文件上传的格式,成功触发 rcube_session::append :

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

继续往下走顺利进入 rcube_session::unserialize 。调试发现传入 PHP 原生反序列化函数 unserialize 的参数 $serialized 中,含有 filename 和 _from 的值:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

可以通过控制请求参数来污染 session 会话,那么是否存在利用的可能性呢?为了方便分析,新建一个辅助的 PHP 文件,并将 rcube_session 类中的 unserialize 和 serialize 放入其中(还可以在 rcube_session::unserialize 中添加 echo 打印信息):

<?phpclass My{    //rcube_session::serialize    protected function serialize($vars)    {        ...    }    //rcube_session::unserialize    public static function unserialize($str)    {        ...    }}$a=$_POST['payload'];$f=My::unserialize($a);echo $f;

与原生反序列化相比,自定义的 session 反序列化函数中主要新增了对 ! 和 | 等字符的处理:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

分析后得出如下结论:

  • • | 符号类似一个分割符,将对象分为 key 和 value ;
  • • ! 符号会将 value 设置为 N; ,表示 NULL 空值。
潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

在 _from 和 filename 这两个可污染 session 的参数中尝试加入 | 和 ! 符号,发现当构造特定请求时, filename 中的字符串被转换为一个序列化对象:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

该序列化对象最后会二次调用 PHP 原生 unserialize 函数,找一个 Roundcube 中的类进行测试,比如 rcmail_sendmail ,成功进入 rcmail_sendmail::__destruct :

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

如果换成其他可利用的 gadget ,就可能会触发 RCE 。

gadget利用链构造

上面测试用的 rcmail_sendmail 类本身就是一个可利用的 gadget ,可实现任意文件删除:

public function __destruct(){    foreach ($this->temp_files as $file) {        @unlink($file);    }}

Roundcube 中可利用的反序列化 gadget 比较多,以下是整理的部分 gadget :

  • • rcmail_sendmail 类 :任意文件删除;
  • • rcmail_attachment_handler 类:任意文件删除;
  • • GuzzleHttpCookieFileCookieJar 类:任意文件写入;
  • • GuzzleHttpPsr7FnStream 类: 任意代码执行;
  • • Crypt_GPG_Engine 类:任意命令执行;
  • • ...

分析发现 filename 参数存在一定限制,无法包含反斜杠等特殊字符,导致 GuzzleHttpCookieFileCookieJar 这种存在命令空间的类无法使用,好在 Crypt_GPG_Engine 没有命令空间,所以可以用来触发 RCE (可借助 pspy 监控命令执行进程 ):

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

利用方式拓展

有没有更通用的利用方式呢?将 filename 后缀设置为类似 s:300 这种长字符长度时,观察到后面还有内容会写入 session ,其中就包含了请求参数 _from 的值:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

因此可以通过控制字符串长度让其与 _from 进行闭合,然后将 gadget 放在 _from 后面,这样也可以触发反序列化操作,并且不存在限制问题:

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

如何实现文件写入

从原理上看,反序列化触发路径应该与 index.php 相同,均位于 Web 目录,但是调试发现命令执行时工作目录变成了系统根目录,因权限不够导致无法写入 shell 。分析后发现问题出在 proc_open 函数,这里参数 cwd 被设置为了 null ,导致工作目录被重置为 / :

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

绕过方法非常简单,最终成功 getshell :

潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析
由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,公众号及文章作者不为此承担任何责任。

原文始发于微信公众号(自在安全):潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月8日14:26:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   潜伏十年的严重漏洞:CVE-2025-49113 Roundcube 反序列化漏洞原理与 gadget 构造深度分析https://cn-sec.com/archives/4145795.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息