跳到主要内容

Redis 多条远程代码执行利用链分析(CVE-2026-25243 / CVE-2026-23631)

· 阅读需 10 分钟
ICE Lab
Institute of Cyber Environment

摘要

2026年5月5日,Redis 数据库中两条远程代码执行利用链被公开披露:RESTORE 机制双重释放漏洞(CVE-2026-25243,CVSSv3 8.8)与主从同步 Lua 引擎释放后使用漏洞(CVE-2026-23631,CVSSv3 8.1)。前者源于 RESTORE 命令反序列化流程中验证器与转换器之间的字节长度解析歧义,可导致 zipmap 编码哈希及 Stream Consumer Group 对象的双重释放;后者利用单线程模型下 Lua 超时钩子与外部主节点 FULLRESYNC 指令的竞态交互,导致全局 Lua 解释器环境被销毁后仍被引用。经身份验证的攻击者在满足配置条件下可将两类内存破坏原语转化为任意内存读写能力,最终实现远程代码执行。本分析分别拆解两条利用链的技术原理与攻击路径。

关键词:Redis;双重释放;释放后使用;远程代码执行;RESTORE;Lua 沙箱

1. 引言

Redis 是广泛使用的内存键值数据库,其单线程事件驱动架构在提供高性能的同时,也引入了独特的安全边界设计——Lua 脚本沙箱、主从复制协议与序列化格式的交互构成了复杂的攻击面。CVE-2026-25243 与 CVE-2026-23631 分别从反序列化解析与主从同步协议两个维度突破了 Redis 的内存安全边界,且两条利用链均需身份验证作为前置条件,属于经认证的远程代码执行(Authenticated RCE)范畴。

2. CVE-2026-25243:RESTORE 双重释放漏洞

2.1 RESTORE 反序列化流程

RESTORE 命令用于将序列化数据反序列化为 Redis 键值对象。其处理流程包含两个阶段:验证阶段(validator)对输入载荷进行格式与长度校验,转换阶段(converter)将验证通过的载荷转换为内部数据结构。两个阶段各自独立解析载荷的字节长度字段。

2.2 验证器与转换器的长度歧义

漏洞的核心在于验证器与转换器对同一载荷的字节长度解析逻辑存在不一致。当处理历史遗留的 zipmap 编码哈希以及 Stream Consumer Group 数据时,验证器按一种长度计算方式通过校验,而转换器按另一种方式解析实际数据,导致转换器写入的字节数超出验证器预期的缓冲区边界。

这种长度歧义在特定载荷构造下可触发双重释放(double-free):转换器在释放旧对象并分配新对象的过程中,因长度计算错误导致同一内存块被释放两次。攻击者通过精心构造的 RESTORE 载荷,利用 Jemalloc 内存分配器的确定性行为,将双重释放转化为堆块重叠(heap chunk overlap),建立任意内存读写原语。

2.3 利用链

利用链可分解为以下阶段:

  1. 载荷构造:构造包含 zipmap 编码哈希或 Stream Consumer Group 数据的恶意 RESTORE 载荷,触发验证器与转换器的长度歧义
  2. 双重释放触发:转换器释放旧对象时因长度错误导致同一内存块被重复释放
  3. 堆布局操控:通过连续 RESTORE 操作操控 Jemalloc 分配器的空闲链表,使新分配对象与已释放对象共享同一内存区域
  4. 任意内存读写:利用堆块重叠篡改对象内部指针或长度字段,建立任意地址读写通道
  5. 代码执行:篡改 Redis 内部函数指针或结合 Redis 重启时的持久化机制(RDB/AOF)实现代码执行

3. CVE-2026-23631:主从同步 Lua 引擎释放后使用漏洞

3.1 单线程模型与超时钩子

Redis 采用单线程事件循环模型处理所有客户端请求。当执行长时间阻塞的慢 Lua 函数时,Redis 内部的超时钩子(timeout hook)会周期性调用事件循环以处理外部 I/O 任务,防止服务器在脚本执行期间完全无响应。这一设计在保证响应性的同时,引入了并发语义的复杂性——Lua 脚本的执行上下文与外部事件处理共享同一线程。

3.2 FULLRESYNC 强制处理与 Lua 环境销毁

漏洞的触发路径如下:

  1. 攻击者通过 SLAVEOF 命令将目标 Redis 实例指定为外部恶意主节点的从节点
  2. 攻击者在目标实例上执行长时间阻塞的慢 Lua 函数
  3. 超时钩子在 Lua 执行间隙调用事件循环处理外部 I/O
  4. 恶意主节点在同步期间发送 FULLRESYNC 指令,该指令在事件循环中被强制处理
  5. FULLRESYNC 处理流程销毁并清空当前的全局 Lua 解释器环境(包括 Lua 虚拟机及堆栈结构)
  6. 事件处理完毕,控制权交回原阻塞 Lua 函数继续执行
  7. 此时底层 Lua 虚拟机及堆栈结构已沦为野指针,构成释放后使用(use-after-free)

3.3 沙箱逃逸路径

释放后使用原语使攻击者可在 Lua 虚拟机已销毁的内存区域上执行操作。通过操控已释放内存的内容(结合堆喷射技术),攻击者可劫持 Lua 虚拟机的函数调用链,绕过 Redis 的 Lua 沙箱限制,执行任意系统命令。该利用链无需依赖特定内存分配器行为,仅利用 Redis 单线程模型下的事件处理时序即可触发。

4. 影响范围

4.1 受影响版本

版本系列受影响范围修复版本
Redis 7.2.x7.2.0 ≤ version < 7.2.14≥ 7.2.14
Redis 7.4.x7.4.0 ≤ version < 7.4.9≥ 7.4.9
Redis 8.2.x8.2.0 ≤ version < 8.2.6≥ 8.2.6
Redis 8.4.x8.4.0 ≤ version < 8.4.3≥ 8.4.3
Redis 8.6.x8.6.0 ≤ version < 8.6.3≥ 8.6.3

4.2 利用条件

两条利用链均需攻击者通过 Redis 认证并具备相应命令执行权限。CVE-2026-25243 需要 RESTORE 命令权限;CVE-2026-23631 需要 SLAVEOFEVAL 命令权限,且目标实例能够连接至攻击者控制的恶意主节点。

5. 修复方案

Redis 官方已在各版本系列发布修复更新:

  • Redis 7.2.x → 升级至 7.2.14
  • Redis 7.4.x → 升级至 7.4.9
  • Redis 8.2.x → 升级至 8.2.6
  • Redis 8.4.x → 升级至 8.4.3
  • Redis 8.6.x → 升级至 8.6.3

对于无法立即升级的环境,建议采取以下缓解措施:

  • 通过 rename-command 禁用 RESTORE 命令以阻断 CVE-2026-25243
  • 通过 rename-command 禁用 SLAVEOF / REPLICAOF 命令以阻断 CVE-2026-23631 的触发路径
  • 配置 requirepass 强密码认证并限制网络访问来源

结论

CVE-2026-25243 与 CVE-2026-23631 分别从反序列化解析一致性与单线程事件处理并发语义两个维度暴露了 Redis 的内存安全边界缺陷。前者的长度歧义问题反映了序列化格式演进中验证逻辑与转换逻辑的耦合风险,后者的 Lua 环境生命周期管理缺陷则揭示了单线程模型中事件处理时序的隐蔽竞态。两条利用链均需身份验证作为前置条件,但一旦满足,均可实现从内存破坏到远程代码执行的完整攻击链。官方补丁已发布,建议受影响用户尽快完成版本升级。

参考文献

[1] NIST NVD. "CVE-2026-25243: Redis RESTORE Double-Free Vulnerability." https://nvd.nist.gov/vuln/detail/CVE-2026-25243

[2] NIST NVD. "CVE-2026-23631: Redis Master-Slave Sync Lua Engine Use-After-Free." https://nvd.nist.gov/vuln/detail/CVE-2026-23631