针对 CVE-2026-109618 开展 PHP 漏洞验证,目标应是确认资产是否处于受影响范围、请求是否进入相关运行时,以及修复是否真正部署,而不是在生产环境触发内存破坏。测试前必须取得书面授权,明确域名、后端实例、测试窗口、请求上限、监控责任人与停止条件。本文采用“运行时盘点+单次正常 multipart 请求+服务端证据关联”的低风险流程,不构造内存耗尽、工作进程崩溃或代码执行载荷。
必须先明确一个限制:正常请求成功不能证明漏洞不存在;刻意触发 OOM 的请求也不能称为无害化探针。 对底层内存破坏问题,生产环境中的安全核验主要依赖可信版本、补丁来源与实际运行实例的对应关系。需要验证触发机理时,应另行审批,在隔离实验环境开展。

一、先确认漏洞事实与验证边界
提供的 IPA 公告摘录将 CVE-2026-109618 描述为与内存不足(OOM)错误处理有关的 PHP 漏洞,并将其与 CVE-2026-109619 合称为 PHP2Shell。摘录说明,漏洞被利用可能导致远程任意代码执行。新加坡网络安全局公告则强调及时更新,并优先处理面向互联网的系统。
这些资料不能替代完整的版本核对:
- 当前摘录未列出可直接采用的完整受影响版本与修复版本矩阵。
- 不能把第三方产品公告中的版本号直接当作上游 PHP 的受影响范围。
- CVE-2026-109618 与 CVE-2026-109619 应分别评估,不能将另一漏洞的配置缓解措施视为本漏洞的修复。
- “php2shell”是资料中的组合称呼,不是所有异常 multipart 请求的统一诊断结论。
正式测试前,应重新打开公告,沿其引用核对 PHP 官方安全发布信息;使用发行版或托管平台提供的 PHP 时,还应检查相应供应商的安全公告与补丁记录。未核实的版本范围应标注为“待确认”,不要填入推测值。
授权单需要写清什么
| 项目 | 建议约定 |
|---|---|
| 目标范围 | 域名、入口地址、实际后端、PHP 工作进程池及资产归属 |
| 允许操作 | 只读盘点、一个正常表单请求、日志与监控关联 |
| 禁止操作 | OOM 诱发、畸形边界、海量字段、并发压测、命令执行载荷 |
| 请求预算 | 每个已批准入口先执行一次,不自动重试 |
| 停止条件 | 新增异常响应、延迟异常、工作进程退出或资源告警 |
| 应急处置 | 谁暂停测试、谁检查实例、谁批准恢复与回滚 |
生产探针应避免支付、发信、导入、发布等有业务副作用的接口。优先使用由维护方提供、经过相同 PHP 请求处理链路的专用测试端点。
二、理解机理:为什么业务代码防护不够
按现有资料描述,CVE-2026-109618 的关键问题在于内存分配失败后的不安全清理:内部数据尚未完成初始化,后续清理过程却可能按有效状态处理它。
理解这一类问题,可以使用以下概念模型:
- HTTP 请求进入 Web 服务器及 PHP 请求处理链路。
- 运行时准备请求相关的内部数据。
- 某次内存分配失败,进入错误处理或清理路径。
- 不完整状态被错误使用,造成内存安全风险。
这不是对具体漏洞函数、堆布局或完整利用链的复现。现有摘录不足以支持这些更细的断言。
其评估意义在于:不能把“业务代码尚未执行”当作安全保证。 如果危险路径发生在请求准备阶段,应用内鉴权、控制器校验或业务异常捕获可能来不及介入。multipart 解析适合作为请求链路核查对象,但不能据此推断“所有上传端点都已证实可利用”。
同样,以下现象都不足以单独定性:
- 返回 500:可能来自业务错误,也可能来自运行时错误。
- 返回 200:只能说明该次请求获得正常响应。
- PHP 工作进程退出:需要排查,不能直接等同于代码执行。
- 应用未记录请求:可能被代理拦截,也可能在应用执行前失败。
三、侦察:把版本指纹落实到实际服务进程
先做只读盘点
由运维在授权主机或对应容器内执行:
php -v
php --ini
php -r 'echo PHP_VERSION, PHP_EOL, PHP_SAPI, PHP_EOL;'这些命令仅提供 CLI 运行时信息。服务器可能同时安装多个 PHP 版本,网站使用的 FPM 或其他服务端运行时未必与命令行一致。
因此,还需要维护方核对:
- 虚拟主机实际连接的服务端进程或 FPM 池;
- 运行进程使用的二进制、配置与安装包来源;
- 发行版完整包版本及对应安全公告;
- 容器运行实例的镜像摘要,而不只是可变标签;
- 负载均衡后是否仍有未更新节点;
- 托管平台是否已完成运行时更新与进程替换。
不要为方便识别版本而在公网部署 phpinfo() 页面。确需应用侧诊断时,应使用受访问控制的内部端点,仅输出必要字段,测试完成后删除。
区分三种证据
| 证据 | 能支持什么结论 | 主要限制 |
|---|---|---|
| HTTP 响应头中的版本 | 提供排查线索 | 可能隐藏、改写或过期 |
| 本地 CLI 输出 | 确认命令行 PHP 状态 | 不代表网站实际运行时 |
| 服务进程、包记录、镜像摘要与供应商公告 | 支持判断实际实例的补丁状态 | 必须逐节点对应 |
对于存在补丁回移的发行版,不能只比较上游版本字符串。判断依据应是供应商公告和实际部署包的对应关系。
四、验证:用正常 multipart 请求核查链路
这里的“无害化探针”是指不包含漏洞触发结构的正常请求,不是能够无风险证明内存破坏漏洞的特殊载荷。其用途仅是验证请求是否到达预期入口、PHP 是否处理了表单,以及证据能否关联。
准备受控端点
由维护方部署一个受访问控制的临时端点,要求:
- 仅允许测试来源访问;
- 不调用命令、不访问数据库、不发送消息;
- 不保存上传文件;
- 只确认一个固定表单字段和请求关联标识;
- 经由待评估的 PHP 服务路径处理;
- 不返回版本、环境变量、绝对路径或完整配置。
该端点只能代表自身经过的链路,不能自动代表其他域名、工作进程池或后端节点。
发送一次正常请求
以下示例使用保留示例域名。执行前应替换为书面授权目标;不要直接指向业务提交接口。
curl --silent --show-error
--connect-timeout 3
--max-time 10
--retry 0
--max-redirs 0
--dump-header probe-response.headers
--output probe-response.body
--write-out '状态码=%{http_code}n总耗时=%{time_total}n'
-H 'X-Assessment-ID: approved-check-001'
--form-string 'assessment_probe=baseline'
'https://php-assessment.example/approved-probe'其中:
--form-string将固定值作为普通字段提交,由工具生成正常的 multipart 编码,不从本地读取文件。- 不使用
-L,避免自动跟随重定向到其他目标。 - 不增加并发、循环或重试。
- 保持 TLS 证书校验,不用
-k绕过错误。 - 超时参数限制客户端等待时间,不保证服务端处理同步终止。
不要增加超大字段、异常嵌套或大量表单项,也不要修改资源限制来“提高命中率”。刻意制造分配失败会改变测试性质,并可能造成可用性影响。
如何解读结果
| 观察结果 | 可以得出的结论 | 下一步 |
|---|---|---|
| 预期响应,服务端确认收到固定字段 | 该端点正常处理了一次 multipart 请求 | 记录链路与节点,不宣称漏洞阴性 |
| 403 或代理拒绝 | 当前来源或路径被访问策略拦截 | 核查策略,不据此判断 PHP 已修复 |
| 超时或 5xx | 存在待解释异常 | 立即停止并检查日志 |
| 工作进程退出、重启或资源告警 | 测试窗口内出现运行异常 | 停止测试,按事件流程排查 |
如果请求因证书、认证或网络策略失败,应先修正测试条件并重新获得执行确认,而不是无上限地重试。
五、证据记录:不崩溃也能形成可复核结论
测试前后,至少关联访问日志、PHP 错误日志、工作进程日志,以及进程重启计数和资源监控。所有系统应使用可对齐的时间基准,并注明时区。
一条完整证据链应能回答:
哪个测试标识,在什么时间,经由哪个入口,落到了哪个后端及 PHP 运行时;当时运行的补丁是什么;请求与服务健康状态分别如何。
建议报告包含:
- 授权编号、测试人与操作时间;
- 入口、后端节点和工作进程池;
- PHP 版本、安装包版本或镜像摘要;
- 官方或供应商公告地址及核对日期;
- 请求参数、关联标识、状态码与耗时;
- 对应日志位置和监控时间窗口;
- 是否发生异常、是否触发停止条件;
- 结论、证据缺口及整改责任人。
响应头可能包含会话信息,归档前应脱敏;原始证据按授权约定受控保存。必要时为证据文件计算摘要,以便复核完整性。
如果出现异常子进程、可疑文件写入或非预期外连,应转入事件响应流程,不继续增加请求来“确认利用成功”。
六、风险判断:将暴露面与补丁状态分开
建议采用以下结论,而不是简单标记“成功”或“失败”:
- 确认处于公告受影响范围:实际运行包与权威公告匹配,但未进行利用验证。报告应明确“未尝试代码执行或 OOM 触发”。
- 确认修复已部署:实际服务进程、包或镜像与供应商修复记录对应,且已完成进程替换。
- 补丁状态待确认:仅有外部指纹、CLI 输出,或缺少供应商回移说明。
- 观察到运行异常:需进一步排查,不能直接归因为该 CVE。
风险排序优先考虑互联网暴露、补丁状态、资产重要性、隔离程度和监测能力。WAF、上传限制和入口鉴权可以作为纵深防御,但不能代替底层运行时修复。
七、整改与回归:确认运行中的代码已经更新
升级与部署
- 从 PHP 官方或供应商公告确认适用修复版本。
- 在预发布环境检查扩展兼容性、启动状态与关键业务。
- 使用可信软件源更新;容器场景重新构建并部署修复后的镜像。
- 按运维流程重启或滚动替换服务进程。
- 逐节点核对实际运行版本、包记录或镜像摘要。
- 观察错误率、延迟、工作进程状态及资源使用。
更新 WordPress、插件或其他应用代码不能替代 PHP 运行时更新。共享主机用户应向服务商索取与自身实例对应的修复确认,而不是只依赖控制面板的版本标签。
回归与清理
复测使用相同的正常 multipart 请求和观察窗口,并确认:
- 所有承载流量的节点均已更新;
- 服务端关联日志完整;
- 正常业务与表单处理未出现回归;
- 旧实例未继续接收流量;
- 临时端点、访问规则和测试文件已清理。
回滚方案不能只写“恢复旧版”。如果旧版仍处于受影响范围,应预先评估隔离、暂停受影响入口或切换至已修复实例等措施,避免恢复业务的同时重新开放风险。
对于 CVE-2026-109618 这类底层问题,合格的授权渗透测试不以“打崩一次”为完成标准。更有价值的交付是:受影响范围有依据、运行实例可定位、补丁状态可复核、业务影响受控制,并且整改后能证明所有实际承载流量的运行时已经完成替换。
- it2021
- it2021.com
- shell
- WordPress
- 代码执行
- 代码执行漏洞
- 渗透测试
- 漏洞验证
- 网络安全
- 访问控制





1F
这个流程比直接打崩一次靠谱多了
2F
权限边界写清楚太重要了,不然后面扯皮
3F
就想知道这种测试一般要申请多久
4F
报告里把证据缺口列出来这点很实在
5F
多版本共存的环境逐个核对确实麻烦
6F
不碰生产环境是对的,出问题担不起
7F
时间基准对齐这个细节平时真容易忽略
8F
低风险流程更适合实际交付,客户也放心
9F
希望以后能出一篇隔离环境复现的教程
10F
想知道临时测试端点一般怎么部署比较稳妥
11F
业务代码没执行不代表安全,这点确实容易忽略
12F
共享主机的用户估计只能干等服务商更新了
13F
正常请求验证链路这个思路挺实用