一、事件速览
2026-10-21,PHP 官方修复并披露两个高危远程代码执行(RCE)漏洞,代号 php2shell 。CNVD 编号 CNVD-2026-41674、CNVD-2026-41675,对应 CVE-2026-109618、CVE-2026-109619 。CVSS v4.0 评分 9.2(Critical/严重),CNVD 综合评级"高危"。时间线要点:官方是"修完即公开"------同日放出修复版本并公开细节,留给企业的响应窗口很短。
影响版本与修复版本对照:
| 影响版本 | 修复版本 |
|---|---|
| PHP 8.5.x < 8.5.12 | 8.5.12 |
| PHP 8.4.x < 8.4.27 | 8.4.27 |
| PHP 8.3.x < 8.3.36 | 8.3.36 |
| PHP 8.2.x < 8.2.35 | 8.2.35 |
PHP 8.1 及更早版本官方不再更新(PHP 团队为 7.4/8.0/8.1 提供最小源码回溯补丁供自行编译)。
两个 CVE 的成因:
- CVE-2026-109619:use-after-free(释放后使用,CWE-416)。请求拥有的内部状态在底层内存被释放后仍存活,同一 worker 后续请求在常规初始化重置前使用了过期状态,导致 RCE。
- CVE-2026-109618:OOM corruption(内存不足破坏)。PHP 在内存不足时中断,内部请求数据只初始化了一半,请求清理时把无效数据当作有效数据,导致 RCE。
为什么这次特别危险:
- 无需认证:已有验证显示未认证请求可在应用层代码执行前触发漏洞。
- PoC 已广泛传播:多国(新加坡、加拿大、荷兰、芬兰、日本等)政府与企业已发预警,部分机构临时关站避险。
- mod_php 风险最高:Apache mod_php 部署已有未认证触发验证,风险优先于 FPM/cgi。
- 波及面极广:所有对外提供 Web 请求的 PHP 部署(PHP-FPM、mod_php、php-cgi、FrankenPHP、LiteSpeed)均受影响,上层 WordPress、Drupal、Joomla、Magento、MediaWiki、Roundcube、phpMyAdmin、Nextcloud、Laravel、Symfony、WHMCS、OpenCart 等全部在列。换句话说,只要站点跑在受影响的 PHP 上,不论用哪个框架,底层漏洞都在。
处置优先级怎么排?先公网、再内网;先 mod_php、再 FPM/cgi;先 EOL 版本、再接近修复线的版本。一句话:能被未认证请求直接打到的资产排最前,先止血再谈根治。
怎么理解 CVSS 9.2?它意味着无需认证、网络可达即可触发、可破坏完整性与可用性------属于"看到就应当立刻处理"的最高档位。权威口径显示已有超百万台暴露服务器受影响,但目前 PoC 已广泛传播、仍在研究利用链、尚未确认大规模实际利用------这正是应急窗口期,错过就要面对真实入侵。
二、先自查:你到底有没有中招
不要只看 php -v。CLI 版本和 Web 实际版本可能不同,一个常见坑是运维只在 CLI 上升级了 PHP,忘了 Web 用的 FPM/mod_php 还是老版本。务必以 Web 实际版本为准。还有人试图用 .user.ini 或应用内 ini_set('memory_limit', -1) 缓解,但这只是请求级、且可能被应用自身覆盖,对这两个 CVE 的路径防护不可靠------缓解项必须在 SAPI 启动前(php.ini / FPM 池 / 服务器配置)生效。
单台自查:
bash
# CLI 版本
php -v
# Web 实际版本(FPM 场景)
php-fpm -v
# 或具体版本
php-fpm8.3 -v
# 当前 Web 用的 SAPI 与关键配置
php -i | grep -E "Server API|memory_limit|session.upload_progress.enabled"
一百台就别逐台手敲了,用循环或 Ansible 批量取:
bash
for h in host1 host2 host3; do
echo "== $h =="
ssh "$h" 'php -v 2>/dev/null | head -1; php-fpm -v 2>/dev/null | head -1; php -i 2>/dev/null | grep "Server API"'
done
对容器/编排环境,单凭进容器 php -v 不够,要同时检查镜像 tag 与运行中的配置挂载:
bash
kubectl exec <pod> -- php -i | grep -E "Server API|memory_limit"
# 核对 Deployment 引用的镜像 digest 是否已更新到修复版本
kubectl get deploy <name> -o jsonpath='{.spec.template.spec.containers[0].image}'
三件必须确认的事:
- Web 用的哪个 SAPI :
php -i | grep "Server API"。mod_php 风险最高,优先处置。 - 是否面向互联网:确认站点公网可达;内网资产也要管,但优先级低于公网暴露资产。
- 版本落在哪个区间:对照上面的对照表。注意底层 PHP 版本决定漏洞是否存在,上层框架(WordPress 等)的更新不能替代底层 PHP 升级。
三、修复优先:升级到修复版本
唯一完整解决方案是升级。四个修复版本:8.5.12、8.4.27、8.3.36、8.2.35。
通用升级思路:
- Debian/Ubuntu(包管理器) :
apt update && apt upgrade php8.3(或对应版本),升级后systemctl restart php8.3-fpm apache2 nginx。注意第三方源(如 ondrej)是否同步了修复版本,先apt-cache policy php8.3看候选版本号。 - RHEL/CentOS :
dnf update php或yum update php,确认 remi 等源的版本号已到修复线。 - 源码编译 :从 php.net 下载对应版本源码,configure 参数保持与现有一致,
make && make install后重启。部分 PECL 扩展可能需重新编译,先在非生产环境验证扩展兼容。 - 容器镜像 :把基础镜像 tag 钉到修复版本(如
php:8.3.36-fpm),重建并滚动发布;建议同时钉镜像 digest,避免 tag 漂移。
PHP 8.1 及更早:官方不再发布二进制更新,但提供了最小源码回溯补丁(7.4/8.0/8.1)。能升到 8.2.35+ 的尽量升;暂时升不动的,至少打回溯补丁(在源码树 git apply 或 patch 后重新编译)并配合下面的缓解措施。
升级后务必验证:再跑一次 php -v / php-fpm -v,确认版本号已到修复线,并做一轮业务冒烟测试(重点看扩展加载、路由、上传功能是否正常)。
生产环境建议灰度推进:先升非核心/内网节点,观察 24 小时无异常再推公网核心。保留旧版本包或镜像,一旦业务异常可快速回退;升级前对配置和代码做快照(尤其 php.ini、FPM 池、.htaccess),避免回滚后配置漂移。
四、不能马上升级?临时缓解配置逐条落地
官方明确:以下只是降低特定攻击路径的暴露,只有升级才是完整解决方案。但应急窗口期,先把这些配置落下去,至少把最危险的路径堵上。

针对 CVE-2026-109618(OOM)
php.ini / FPM 池 / Apache 配置中设置。关键是用 php_admin_value,应用层 ini_set() 无法覆盖它:
ini
; FPM 池 (www.conf) 示例
php_admin_value[memory_limit] = -1
php_value[post_max_size] = 8M ; 不需要上传的应用设 8M
php_value[upload_max_filesize] = 6M ; 必须低于 post_max_size
需要文件上传的应用把 post_max_size 设 32M、upload_max_filesize 设 24M。Apache mod_php 写法:
apache
<IfModule mod_php.c>
php_admin_value memory_limit -1
php_admin_value post_max_size 8M
php_admin_value upload_max_filesize 6M
</IfModule>
确认没有池级/目录级/.user.ini 把它改回有限值------应用层覆盖会让你误以为已缓解,实际仍是漏洞。
为什么 memory_limit=-1 能缓解这条 OOM 路径?OOM corruption 发生在 PHP 因内存不足而中断分配时,设为无限制后该中断路径不再被触发,请求要么正常完成、要么由 cgroup 边界兜底,从而避开了"半初始化数据被当作有效数据"的窗口。
在 Web 服务器或反向代理层对解码后请求大小、输入字段数、multipart 段数、header 数量、嵌套深度设限,这些限制必须覆盖没有可用 Content-Length 的请求(如分块传输)。Nginx 示例:
nginx
client_max_body_size 8m;
# header 数量、字段数、嵌套深度可结合 lua 模块或 modsecurity 规则限制
作为纵深防御,可在反向代理叠加 WAF 规则(如 modsecurity CRS 的请求体/参数数量限制)进一步收敛攻击面,但要明确:WAF 只是争取时间,不是修复,核心仍是升级。
容器或 cgroup 限制作为可用性边界,优先采用"只杀受影响 worker"策略。注意:不要用 RLIMIT_AS / RLIMIT_DATA 替代 memory_limit = -1,否则无法真正消除该路径。另外 memory_limit=-1 会让单请求可能吃掉更多内存,必须配请求大小限制和 cgroup 边界,避免被当成 DoS 放大器。
针对 CVE-2026-109619(use-after-free)
ini
; 必须在请求解析前生效,用 php.ini / FPM 池 / 服务器配置
; 不要依赖 ini_set() 或 .user.ini(那是请求级,太晚)
php_admin_value[session.upload_progress.enabled] = 0
; PHP 8.5 上额外阻断已确认的 fatal backtrace 路径
php_admin_value[fatal_error_backtraces] = 0
改完重启所有 worker (FPM 用 systemctl restart php8.x-fpm,mod_php 重启 Apache),否则配置不生效。
修复攻击者可触达的 fatal error 和执行超时:排查回调、上传/导入处理、清理阶段的失败点。隐藏诊断信息(error_reporting / display_errors / @)没有用,必须真正修复逻辑。
验证缓解是否生效:用 php -i | grep -E "memory_limit|session.upload_progress.enabled|fatal_error_backtraces" 在 Web 上下文中确认这些值确实为预期(防止应用层覆盖),再观察一段时间有无异常 fatal。
五、当资产不是 1 台而是 100 台:规模化应对框架
一台机器好办,一百台甚至上千台暴露在公网的 PHP 资产,靠手工逐台操作和记脑图不现实。这里给一套"检测→优先级→修复→缓解→隔离→监测→加固"七步闭环方法论,并以 ManageEngine 产品体系为例说明工具如何做编排层。
1. 检测与优先级:先回答"谁在洞里"
我们用 Vulnerability Manager Plus 持续扫描全网主机的操作系统与 1700+ 第三方应用,按 CVSS、可利用性、补丁可用性、威胁情报、EPSS 可能性排序,直接把"PHP 8.3.30 / 低于 8.3.36"这类条目标红并附 CNVD/CVE 与 CVSS,省去人工比对。它的三个能力在这次各有侧重:
- 零日漏洞缓解视图:把尚无补丁的漏洞单独列出,避免淹没在常规列表里。
- Web 服务器加固(基于 200+ 条 CIS/STIG 基准):直接识别 mod_php 高危配置、memory_limit 被改回有限值等错配。
- 高风险软件审计:把 8.1 及更早的 EOL 版本单独拉出来。
这一步直接回答两个问题:哪些主机低于修复线、哪些还在跑 EOL。
2. 修复与缓解:能升就批量升,升不动先全网堵
Endpoint Central 的补丁管理覆盖操作系统、应用与移动端 1100+ 第三方应用,自动扫描-检测-测试-部署,我们用它批量把几百台主机的 PHP 升到修复版本。暂时升不动的,用自定义脚本一键下发缓解配置:
- 写 php.ini / FPM 池、改
memory_limit=-1。 - 关
session.upload_progress.enabled、限post_max_size、关fatal_error_backtraces。 - 脚本按刷新周期(我们设每 90 分钟)加启动/登录执行、失败重试,保证全网一致。
这样能避免个别主机被应用层覆盖造成的"假缓解"。
3. 隔离与止血:先把暴露面缩起来
- 暂无法修复又暴露公网的资产,用系统隔离策略(NAC)按规则隔离,缩小暴露面。
- 确认失陷的端点,用 Endpoint Central 的 EDR 隔离、终止恶意进程、回滚。
4. 监测利用迹象:盯组合信号,而非单条告警
Log360 集中采集并分析 Web 服务器、应用、认证、终端日志。我们把研判重点放在几类线索:
- www-data / www 用户起的外连进程。
curl|sh或wget|bash这类异常命令执行、反弹 shell 连接。- 新出现的提权文件与可疑 cron 项、异常账号登录与提权。
- 大量指向未知外网 IP 的出站连接。
这些线索单独看未必致命,但组合出现(如"非业务时段 www 用户起了外连 + 新增可执行文件")基本就是失陷信号。EDR 按 MITRE ATT&CK 识别妥协指标(IoC),能在勒索、持久化、横向移动等阶段提前告警,而不是等被加密了才发现。
如果集中日志还没覆盖到某台主机,可以先做一轮命令行初筛,快速定位可疑资产再交给 Log360 做横向关联:
bash
# 看 www 用户起的进程与外连
ps -eo user,pid,cmd | grep -E '^www'
ss -antp | grep ESTAB
# 查近期被改的可执行/脚本文件
find /var/www -type f -mtime -1 \( -perm /u+x -o -name '*.php' \) 2>/dev/null
初筛的意义不在于确诊,而在于在百台规模里先把"最不对劲"的那几台挑出来,把人力压到刀刃上。
5. 防止横向移动:在 Web 与内网之间加一道墙
RCE 得手后攻击者常顺手拿服务器特权凭据横向,用 PAM360 收敛服务器凭据、做轮换与审计,在"拿下 Web"与"拿下内网"之间加一道墙。
核心方法论仍是:先升级、升不动就缓解、全程监测。工具把这套流程在一百台机器上编排执行、跑齐跑对。
六、行动清单
- 跑
php -v和php-fpm -v,记录 CLI 与 Web 实际版本(以 Web 为准) - 确认 SAPI(
php -i | grep "Server API"),标出所有 mod_php 部署 - 对照影响版本表,列出低于修复线的主机清单
- 标出所有面向互联网的 PHP 资产(优先处理)
- 对低于修复线的主机,升级到 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35
- 升级后重启 FPM/Apache,再跑版本确认 + 业务冒烟测试
- 不能马上升级的:设
memory_limit=-1+ 限制post_max_size - 关
session.upload_progress.enabled=0+(8.5)fatal_error_backtraces=0,重启 worker - 在反向代理层限制请求大小/字段数/header 数/嵌套深度(覆盖分块传输)
- 开启日志集中监测,排查是否已被入侵(异常进程/命令/外联)
- 收敛服务器特权凭据,降低横向移动风险
七、小结
漏洞会反复出现,下一次不一定叫 PHP2Shell。比单次应急更重要的是建立常态化的"资产可见 + 快速修复 + 临时缓解 + 持续监测"能力------这样无论哪个组件爆出 9.2 分的 RCE,你都能在窗口期内把处置流程跑完,而不是从零开始慌。