PHP2Shell hero 卡片:从一次失败的请求到远程代码执行,CVE-2026-109618 与 CVE-2026-109619
Engineering & Research

OrcaCyber Research - PHP2Shell:一次失败的请求如何演变为远程代码执行

作者

Rowan Sterling

发布日期

最新模型 · 20查看全部模型 →
基准测试:Artificial Analysis · 每日更新
返回全部文章

本次调查中的概念验证是使用OrcaCyber Zero和OrcaCyber Ultra模型创建的。研究包记录了源代码级分析、使用改编的公开漏洞利用进行的受控复现、内存泄露产物、进程崩溃以及命令执行证据。所提供的文件并未独立记录每个模型执行了哪些步骤;模型归属由研究团队提供。

致命的内存耗尽状况应安全地终止请求。在这里,它可能在原生状态仅部分初始化时中断 PHP,留下会持续到下一个请求的引用。结果是跨请求的内存生命周期违规,在测试环境中造成的后果从信息泄露到远程代码执行不等。

关键证据一览

• 目标 — PHP 8.4.26,Apache/mod_php,单工作进程,隔离的 Docker 实验环境。

• 崩溃日志 — 在提供的摘录中,有一次 SIGABRT 和三次 SIGSEGV 工作进程退出。

• HTTP 响应 — URL 解码后的 PHPSESSID 值中有 819,200 字节。

• 执行证明 — code>uid=33(www-data) gid=33(www-data) groups=33(www-data)/code>.

• 回归 — 报告描述了针对已修补的 PHP 8.4.27 的四次未成功尝试;原始运行结果未随附提供。

来源:上传的 REPORT.md、crash_evidence.log、leak_attempt.resp 和 rce_proof_8426.txt。下文所述的展示件将这些工件复现为排版后的证据面板;它们并非照片或原生终端截图。

1. 漏洞:请求边界处的所有权失效

这两个相关问题涉及被中断的请求初始化以及陈旧的运行时全局指针。在相关的 PHP 架构中,multipart/form-data 处理和会话上传进度回调可能在正常用户应用程序代码之前运行。异常的控制流转换,包括 code>zend_bailout()/code>,可能会跳过预期的清理,并使状态指向之后被释放或复用的内存。

安全不变量:暴露给请求 B 的 worker 全局引用,绝不能指向其所有权和生命周期已随请求 A 结束的内存。所报告的故障违反了该不变量。

所演示的端点是一个仅返回 OK 的最小 PHP 页面;该漏洞利用叙述并不依赖于应用层 SQL 注入、文件包含或反序列化端点。

2. 技术序列

• A1 — 中断。分片上传和上传进度处理在清理期间触发 OOM,导致会话状态残留。

• B1 — 泄漏。后续请求会导致会话 Cookie 序列化读取超出有效会话 ID 的范围。

• 地址恢复。泄露的指针值被用于推断该构建中相关的库与堆布局。

• A2/B2 — 数据损坏。 另一个双请求序列会构造并重定向关机时使用的过期数据。

• 结果。改编后的公开漏洞利用程序报告以 www-data 身份执行命令。

Five-step diagram of the PHP2Shell chain from OOM interruption to command execution as www-data, reconstructed from the research bundle

证据附件:所提供文件实际显示的内容

证据 A — 来自 Apache 日志的工作进程终止

• code>[core:notice] [pid 1:tid 1] AH00051: 子进程 pid 54 因信号 Abort (6) 退出,可能在 /etc/apache2 中生成核心转储/code>

• code>[core:notice] [pid 1:tid 1] AH00051: 子进程 pid 55 退出信号为 Segmentation fault (11),可能在 /etc/apache2 中生成核心转储/code>

• code>[core:notice] [pid 1:tid 1] AH00051: 子进程 pid 58 退出信号为段错误 (11),可能在 /etc/apache2 中生成核心转储/code>

• code>[core:notice] [pid 1:tid 1] AH00051: 子进程 pid 61 退出信号 Segmentation fault (11),可能在 /etc/apache2 中生成核心转储/code>

来自 crash_evidence.log(2026年10月23日)的排版摘录。多个工作进程退出表明存在内存安全故障;仅凭崩溃并不能确定 RCE。

• 代码>HTTP/1.1 200 OK/代码>,二进制数据已省略。

• code>服务器:Apache/2.4.69 (Debian)/code>

• code>X-Powered-By: PHP/8.4.26/code>

• code>Set-Cookie: PHPSESSID=[已省略二进制数据]/code>

• 编码后的 Cookie 长度:2,330,754 字节。

• URL 解码后的值:819,200 字节。

测量值直接由 leak_attempt.resp 计算得出。二进制值已被有意省略,以避免复现任何泄露的进程内容。

附件C——执行证明

code>uid=33(www-data) gid=33(www-data) groups=33(www-data)/code>

rce_proof_8426.txt 的确切内容,按所提供原样。它支持所报告的执行结果,但并非完整的命令/会话记录。

Evidence summary card: four worker exits, an 819,200-byte URL-decoded session cookie, and uid=33 execution context

附件 D — 会话生命周期修复

• code>static inline void php_rinit_session_globals(void)/code>

• code>@@ -121,6 +120,7 @@ static inline void php_rinit_session_globals(void)/code>

• code>* 在请求启动期间、RINIT 之前重新编码会话,此时没有用户/code>

• code>/* 在 RINIT 之前运行:不得调用任何用户代码,参见 php_session_unserialize_init() *//code>

• code>/* 这段代码在 RINIT 之前运行,因此我们需要尽早清除这些内容 *//code>

• code>php_rinit_session_globals();/code>

session.c.diff 中选定的源差异行。此更改显式地在普通 RINIT 之前重置会话全局状态。

3. 证据为何重要

内存泄露为进程崩溃与利用链之间提供了桥梁。一个大小异常且内嵌二进制数据的会话值,与运行时将无效内存解释为 Zend 字符串的情况相符。研究报告进一步描述了从泄露窗口中提取代码地址和堆地址。证据包包含原始响应,但不包含能证明每个已恢复地址的独立脚本。

该 RCE 产物显示的是 www-data 安全上下文。它并不能证明已获得 root 访问权限、攻陷了生产环境,也不能证明可完全移植到任意 PHP 部署环境。单工作进程的实验室配置很重要,因为请求顺序和工作进程亲和性会影响该机制。

4. 修复底层生命周期,而不只是症状

提供的 PHP 补丁提交 01a40e89fbfc(“Avoid state corruption via bailout”)的源代码差异显示:提前进行会话全局初始化、对分配器 OOM 处理的更改,以及更广泛的重置/清理逻辑。这些更改旨在防止原生状态在请求中断后以无效状态残留。仅修复 cookie 编码路径本身并不能恢复这一内存所有权保证。

研究报告指出,针对 PHP 8.4.27 的尝试在四次试验中均未产生异常 cookie、崩溃或 RCE 证明。实际的已修补版本记录不在本材料包中,因此该对比仅作为研究人员的观察结果报告,而非可独立检查的证据材料。

5. 防御行动

• 立即。将受影响的受支持 PHP 版本系列升级到其安全修复版本,并使用供应商公告确认确切的软件包状态。

• 减少暴露面。 考虑限制 multipart 输入,并在未使用时禁用 code>session.upload_progress/code>;这些措施不能替代补丁。

• 检测。检查请求初始化期间的崩溃、意外的 500 错误以及过大的code>Set-Cookie/code> 响应头。

• 保障。 使用具有生产代表性的工作进程池重新测试,并验证旧会话状态无法跨请求持久化。

6. OrcaCyber 研究方法论

有价值的研究任务不仅在于发现单个不安全操作;还在于追踪贯穿请求解析、分配器行为、持久化原生全局变量、序列化和关闭过程的完整不变量违反。据研究团队归因,本次调查中使用 OrcaCyber Zero 和 OrcaCyber Ultra 创建了 PoC。公开工件集支持技术复现,但不提供逐模型的执行轨迹,也不能证明自主漏洞发现。

证据阶梯:源代码假设 → 可达触发点 → 运行时故障 → 信息泄露 → 执行证明 → 修复版本回归。相比漏洞描述或仅有崩溃的结果,这一顺序能带来更强的信心。它还能促使在缺少源文件或原始执行日志时,明确报告不确定性。

7. 范围与局限性

本出版物描述了一个经过授权的隔离 Docker 实验环境。该漏洞利用基于此前已发布的 PHP2Shell 研究,相关本地适配记录在随附报告中。该材料包包含脚本、差异补丁、响应字节、日志和证明输出,但不包含完整的上游漏洞利用代码检出、原生截图以及完整的原始补丁回归测试记录。本内容未声称存在任何真实世界的受害者或客户遭受入侵。

源与工件

主要来源:提供的 php2shell-report-bundle.tar.gz(REPORT.md;report-CVE-2026-109618.md;report-CVE-2026-109619.md;crash_evidence.log;leak_attempt.resp;rce_proof_8426.txt;PHP 源代码差异)。公开背景:PHP 安全公告 GHSA-w8hw-w9fx-j79w 和 GHSA-6wmf-4rv5-p3rp;PHP 安全版本发布公告。公开漏洞利用归属:9bie/php2shell-bypass-aslr-exp。研究仓库:orcacyber-php2shell-research。

The public orcacyber-php2shell-research GitHub repository README on the OrcaCyber PHP2Shell defender research artifacts and its defensive scripts

要点:一次请求失败;一个指针仍然存活;下一次请求却信任了它。理解这个漏洞的难点在于用可观察的证据建立这种关联。

本文中的对比1

根据本文内容识别