PHP “php2shell”(CVE-2026-109618/109619):从 session.upload_progress 到多条 RCE 攻击链


前言

TL;DR:CVE-2026-109618 和 CVE-2026-109619 是 php 核心中两个 CVSS v4.0 评分 9.2 的远程代码执行漏洞,影响 php 5.4.0 至 8.5.x,根源于 session.upload_progress 处理逻辑及相邻的反序列化内存管理缺陷。与早期仅存在 LFI 利用的认知不同,当前已验证的攻击链包括会话文件注入 + LFI、var_destroy UAF → 处理器覆盖,以及处理器不匹配 → __destruct 对象注入三条独立路径。设置 session.upload_progress.enabled = Off 和 session.use_strict_mode = On 是必要的临时缓解,但不能替代打补丁——GMO Flatt Security 已明确更新其建议,指出仅关闭该功能无法完全阻断攻击。修复版本为 8.2.35、8.3.36、8.4.27、8.5.12(计划于 2026 年 10 月 21 日发布);PHP 5.x、7.x、8.0、8.1 已 EOL,不会获得官方补丁。

一、漏洞机制:不止于 LFI

攻击链 1:会话文件注入 + LFI(逻辑缺陷)

这是此前已知的路径,但 ikow 的验证确认其触发条件比原先认为的更宽:session.use_only_cookies 可被 POST 体绕过,且 upload_progress 中的文件名未经校验即被原样写入 session 文件。攻击者仍可在 session.upload_progress.enabled = On(默认)且应用存在 LFI 汇点时,通过 multipart 请求将可控内容写入 session 文件并包含执行。

攻击链 2:var_destroy UAF → 处理器覆盖(内存破坏)

这是 php2shell 区别于传统 LFI 利用的核心。dinosn 的独立研究在 PHP 8.5.5 中确认:ext/standard/var_unserializer.re 的 var_destroy() 在遍历析构列表时,仅在显式 __wakeup/__unserialize 用户代码分发前后提升 BG(serialize_lock),而同一循环中的三处隐式分发点——包括 zval_ptr_dtor 对 __wakeup 返回值、__unserialize 参数副本,以及 dtor 列表槽位本身的销毁——均在无锁状态下执行。当 __destruct 被触发且内部再次调用 unserialize() 时,外层 var_hash 的回指数组扩展块已被 efree,内层 R:N 引用会踩中悬空的 entries.next 指针,造成 php_var_unserialize 中的 heap-use-after-free 读。在 efree 与内层访问之间的窗口进行堆喷,可将泄漏的 8 字节替换为攻击者控制的 zval *,实现任意指针分发。

ikow 的 PoC 将此 UAF 与 unserialize() + /proc/self/mem 结合,形成了已验证的 ASAN + rce 链。这意味着攻击者不再需要目标应用存在 LFI 汇点,只要 PHP 进程能够处理攻击者触发的 unserialize() 路径(例如通过 session.upload_progress 的序列化写入与读取),即可尝试触发内存破坏。

攻击链 3:处理器不匹配 → __destruct 对象注入(反序列化)

ikow 还验证了一条跨目录处理器不匹配的路径:当序列化处理器配置存在不一致时,__destruct 可在解码失败后仍然触发,配合 POP gadget 链完成对象注入与代码执行。这进一步说明,session.upload_progress 写入 session 的序列化数据本身就可以成为攻击载体,而不仅仅是被 LFI 包含的“静态文件”。

另一个持久化面:RSHUTDOWN 序列化器泄漏

同一研究指出,PS(serializer) 在 RSHUTDOWN 阶段未被重置,导致 FPM 环境下跨请求的序列化器状态泄漏。虽然这不是直接的代码执行原语,但它扩大了处理器不匹配攻击链的触发窗口。

二、CVE 定性与修复状态

项目 状态
CVE 编号 CVE-2026-109618 / CVE-2026-109619(研究社区命名 “php2shell”)
CVSS v4.0 9.2(PHP 官方评级;泄漏信息曾声称 10.0,但非官方数值)
影响版本 PHP 5.4.0 – 8.5.x(所有包含 session.upload_progress 的版本)
修复版本 8.2.35、8.3.36、8.4.27、8.5.12(计划 2026-10-21 发布)
EOL 分支 PHP 5.x、7.x、8.0、8.1:官方无补丁,需迁移或回移
官方技术细节 截至补丁发布前未完全公开;PoC 与 ASAN 证据来自独立研究

需要特别澄清与 CVE-2020-7062 的关系:后者是 session.upload_progress.cleanup = 0 时上传失败触发的空指针解引用 DoS,属于独立的可用性问题,不构成 php2shell 的 rce 原语。本文讨论的 RCE 链根植于 var_destroy UAF 和反序列化处理器逻辑,不应与 CVE-2020-7062 混为一谈。

三、缓解与加固

第一层:立即临时缓解(必要但不充分)

; php.ini
session.upload_progress.enabled = Off
session.use_strict_mode = On

ikow 和多家通告均将此列为临时措施。但 GMO Flatt Security 在 2026-10-21 明确更新:session.upload_progress.enabled=0 单独无法完全阻断攻击,攻击仍然可能通过其他路径(尤其是 unserialize() 相关的 UAF 链)发生。因此,不能将此视为修复。

第二层:补丁(唯一根本性修复)

升级至 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 是消除全部已知攻击链的唯一方式。对于 PHP-FPM,必须对每个 serving pool 应用配置并 reload workers,因为 CLI 的 php -i 结果不代表 Web SAPI 已生效。mod_php 部署需更新配置并重启 Apache。

第三层:无法立即打补丁时的纵深防御

  1. 限制 unserialize() 的攻击面:审计应用中所有用户输入可触及的 unserialize() 调用点。var_destroy UAF 的触发需要攻击者能够引发 __destruct 内的再次 unserialize(),收紧反序列化入口可降低被利用概率。
  2. 隔离 EOL 部署:PHP 5.x–8.1 无官方补丁,应将此类实例从互联网直接暴露面移入受信网络,或向操作系统/托管商索取回移补丁。
  3. FPM 配置审计:确认 session.upload_progress.enabled 在所有 pool 中均为 Off,并检查 conf.d 是否有更高优先级的 .ini 将值覆盖回 On。
  4. 自定义 session handler 警告:若应用使用自定义 session handler 且未实现严格的 ID 校验,session.use_strict_mode = On 可能失效。

第四层:补丁发布后的验证

# CLI 验证(必要但不充分)
php -i | grep -E "session.upload_progress.enabled|session.use_strict_mode"

# Web SAPI 验证(必须)
curl -s http://localhost/info.php | grep -i "upload_progress\|use_strict_mode"

确认 Web 请求返回 session.upload_progress.enabled => Off 且 session.use_strict_mode => On,同时 PHP 版本已处于修复分支。

四、小结与行动清单

php2shell 的本质是 session.upload_progress 的序列化写入/读取路径与 var_destroy 的反序列化内存管理缺陷叠加,其影响面从“LFI 放大器”升级为“无需 LFI 的内存破坏 RCE”。PHP 官方仅为 8.2–8.5 四个分支提供修复,意味着大量 EOL 部署将长期暴露。

当下可执行清单:

优先级 行动 状态/说明
P0 升级至 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 唯一根本性修复
P0 对所有 serving pool 设置 session.upload_progress.enabled = Off、session.use_strict_mode = On,并 reload 临时缓解;单独不足
P1 审计 unserialize() 用户输入入口,收紧 POP gadget 可达性 降低 UAF 链触发概率
P1 将 PHP 5.x–8.1 实例迁出直接暴露面或索取回移补丁 官方无补丁
P2 检查 conf.d 覆盖、自定义 handler 的 strict mode 有效性、FPM 配置一致性 防止缓解被绕过

参考材料

  • Qi Deng, php2shell — CVE-2026-109618/109619 Research, GitHub ikow/php2shell-poc
  • dinosn, PHP 8.5.5 — var_destroy __destruct reentrancy UAF, GitHub dinosn/php-8.5.5-var_destroy-uaf
  • CERT-EU 安全风险通告(2026-10-21)
  • GMO Flatt Security 官方博客(2026-10-21,含“enabled=0 不充分”更新)
  • The Hacker News / Sansec / Mallory 时间线与修复版本报道

手机扫码阅读

-

友加畅捷管理系统标准版 UpdateWayJJD接口SQL注入漏洞

评 论