PHP2Shell 的官方缓解措施写得很细,但第一步永远是同一件事:搞清楚你到底在跑哪个版本的 PHP。这一步比想象中容易出错——绝大多数人查到的版本是错的。

一、最常见的误区:CLI 版本 ≠ 网站版本

服务器上执行 php -v 看到的,往往是命令行用的那个 PHP。而你的网站跑的是 PHP-FPM 或 Apache 模块,是另一套二进制、两份配置。两者版本不同是常态。

# 命令行版本(仅供参考)
php -v

# 网站实际使用的版本(这才是要判断的)
php-fpm -v
php-fpm8.3 -v
php-fpm8.0 -v

# 确认 FPM 进程实际加载的配置
php-fpm8.0 -i | grep -E "Loaded Configuration File|Configuration File"

# 确认正在运行的 FPM master 用的哪个版本
ps -ef | grep php-fpm | grep master

二、宝塔面板用户:三步确认

如果你的服务器用宝塔面板,路径是这样的:

  1. 看站点实际版本:网站 → 找到目标站点 → 设置 → PHP 版本。这里显示的才是这个站点跑着的版本。
  2. 看装了哪些版本:软件商店 → PHP,能看到服务器上安装了哪些版本,以及每个版本的服务状态。
  3. 看 FPM 配置:软件商店 → PHP → 某个版本 → 配置文件,确认 memory_limit、post_max_size 等关键项的实际取值。

注意宝塔的一个常见坑:装了多个 PHP 版本不代表它们都安全。装了 8.3 但站点仍选着 8.0,那么风险就还是 8.0 的。而且 8.1 及更早版本官方已经不再更新,除非你的发行版或面板提供了回移植补丁,否则它们属于「无补丁可用」状态。

三、对照这张表判断自己是否中招

你的网站 PHP 版本是否受影响该做什么
8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 及以上否确认服务已重启、常驻进程已 reload,并做一次入侵排查
8.2.x < 8.2.35
8.3.x < 8.3.36
8.4.x < 8.4.27
8.5.x < 8.5.12
是立即升级到修复版本;无法升级则按临时缓解措施处理
8.1.x / 8.0.x / 7.x是(且官方已停止更新)最需要处理的一档:要么升级到受支持版本,要么向供应商确认回移植补丁
发行版自带包(如 Debian/Ubuntu 的 php 8.2-x)看包版本,不看 PHP 版本号安全修复常被回移植到既有包版本,「主版本没变」不等于「补丁没打」

四、别只查自己的站点

这类事件的排查范围往往比想象中大。NCSC(英国)在公告里专门提醒:评估不能只限于对外可访问的网站。下面这些位置也可能在跑 PHP:

  • 容器与编排环境:镜像 tag 没变不代表里面没打补丁,需要看基础镜像的 digest 与构建时间;跑在 K8s 里的老副本最容易被漏掉。
  • 内置 PHP 的第三方产品:phpMyAdmin、Roundcube、MediaWiki 这类自带的 PHP 运行时,你可能根本不知道它在哪。
  • 管理后台与内部工具:运维面板、监控面板、CRM、工单系统,很多直接嵌在 PHP 上。
  • 「不用 PHP 也会受影响」的场景:不少商业软件与开源产品把 PHP 打包在后台,采购时不会出现在你的技术栈清单里。荷兰 NCSC 维护了一个 GitHub 清单,专门列出哪些第三方软件内置了 PHP。
  • 本机之外的机器:内网服务器、老测试机、已经交出去但还在续费的主机。

五、自查清单

照着这份清单过一遍,大约十分钟:

  • 用 php-fpm -v(而不是 php -v)确认每个站点实际运行的 PHP 版本。
  • 对照上面的影响表,列出所有低于修复版本的站点清单,并标注是否对外可访问。
  • 列出所有对外暴露的 PHP 应用,包括你自己没意识到的那部分。
  • 确认每个站点的 PHP 运行形态:mod_php / PHP-FPM / CGI —— mod_php 优先级最高。
  • 查一遍 10 月 21 日前后的访问日志与错误日志,是否有异常的大请求、worker 崩溃或 500 激增。
  • 确认升级路径:面板能否直接切到更高版本、是否有依赖扩展需要重新安装、是否需要停机窗口。

六、接下来

确认受影响之后,处置顺序是:先升级(唯一完整解),升级不了再看《不能马上升级?官方给的临时缓解措施与它们的边界》;如果站点在此期间对外暴露过,无论是否升级,都要补做一次《升级完成不等于结束:PHP2Shell 入侵排查与恢复清单》里的检查。