全部文章
漏洞6 分钟阅读

PHP2Shell 正被利用:如何检查你的应用是否暴露

Server rack with one glowing exposed server shielded by a translucent blue security shield

如果你觉得“我又不用 PHP”,也许你是对的。但很多独立开发者的技术栈都在某个角落悄悄用着它:WordPress 营销网站、Laravel API、托管落地页的廉价共享主机、几年前搭的管理后台。这周这一点很重要,因为 PHP 本身的两个严重漏洞(被称为 PHP2Shell)在短短几天内就从“补丁已发布”变成了“已被在野利用”。

这篇文章是给开发者的简短版:发生了什么、如何查明你的东西是否受影响,以及今天该怎么做。不需要安全团队。

发生了什么

10 月 21 日,PHP 项目发布了两个漏洞的修复:CVE-2026-109618 和 CVE-2026-109619。两者的 CVSS 评分均为 9.2,根据 Arctic Wolf 的分析文章,它们可以让未经身份验证的攻击者在用 PHP 处理 Web 请求的服务器上执行代码。

这些漏洞存在于 PHP 自身的请求处理生命周期中,而不是某个框架或插件里:

  • CVE-2026-109618 是一个内存损坏漏洞,当请求数据只完成部分初始化时,内存不足状况中断 PHP 就会触发它。
  • CVE-2026-109619 是一个释放后使用(use-after-free)漏洞:属于某个请求的状态可能残留下来,被同一 worker 上后续的请求读取,还可能泄露内存内容。

第二点值得停下来想一想。Qualys 指出,泄露的 worker 内存中可能包含密码、令牌和 API 密钥。所以即使没人在你的服务器上拿到 shell,机密信息也可能被带走。

补丁发布后事态发展迅速,规模也很大:The Hacker News 引用 Censys 的估算,仍有超过 3200 万个 PHP 服务运行着受影响的版本。

  • 据 BleepingComputer 报道,Amazon 的威胁情报团队表示,针对性攻击在修复发布前四天就已开始。
  • 10 月 24 日,Perplexity 的一名研究人员确认在蜜罐上成功实现了代码执行(The Hacker News)。
  • 10 月 26 日,CISA 将这两个 CVE 加入其已知被利用漏洞(KEV)目录,并要求美国联邦机构在 10 月 29 日前完成修复。

为什么这对小型应用也很重要

攻击者在这里不会按公司规模挑选目标。他们扫描整个互联网,寻找任何像 PHP 一样响应的服务,然后尝试利用漏洞。VPS 上一个被遗忘的副业项目和大型电商网站一样容易被攻击到。

有几个细节让这次漏洞特别值得立即处理:

  • 它与你的代码无关。Arctic Wolf 指出,由于漏洞位于 PHP 的请求处理中,是否暴露并不取决于你运行的是哪个应用。一个写得完美的 Laravel 应用,跑在旧的 PHP 版本上依然会暴露。
  • 很多服务器配置都在影响范围内。Apache 搭配 mod_php 被认为风险最高,但 PHP-FPM、php-cgi、FrankenPHP 和 LiteSpeed 也都被列为受影响,捆绑 PHP 的产品和设备同样如此。
  • 旧版 PHP 很常见。Qualys 报告称,在它能识别版本的 PHP 安装中,约 71% 已经停止支持(EOL)。如果你用的是 8.1 或更旧的版本,上游不会再为你提供常规修复。

如何检查你的应用

每台服务器你只需要一个答案:是否有东西在用 PHP 处理 Web 请求,具体是哪个版本?

1. 列出你托管的所有东西。不只是主应用,还包括营销网站、博客、文档、预发布环境、管理工具以及任何子域名上的东西。被遗忘的那些才是最危险的。

2. 查看响应头。很多 PHP 配置会在 X-Powered-By 或 Server 头中自报家门。没有这个头并不代表没有 PHP(可以用 expose_php = Off 关闭),但有这个头就能快速确认。详细的错误页面是另一个破绽:生产环境中的 PHP 堆栈跟踪会准确告诉攻击者你在运行什么。

curl -sI https://your-site.example | grep -i -E 'x-powered-by|server'
# X-Powered-By: PHP/8.3.20   <- PHP, and an old patch level
详细错误页面和堆栈跟踪:如何关闭它们

3. 检查实际处理 Web 流量的版本,而不只是 CLI。服务器上的 php -v 报告的版本可能与 Apache 或 PHP-FPM 实际使用的不同;Qualys 特别指出了这一点。检查 FPM 二进制文件或 Web 服务器的 PHP 模块,或者询问你的托管商。

php-fpm8.3 -v              # or php-fpm -v, depending on your distro
apache2ctl -M | grep php   # is mod_php loaded?

4. 与已修复的版本进行比较。如果你通过 Linux 发行版安装 PHP,修复可能已被回移植到版本号看起来较旧的软件包中,所以请查看发行版的安全公告,而不是只看版本号。否则,你至少需要:

  • PHP 8.5:8.5.12
  • PHP 8.4:8.4.27
  • PHP 8.3:8.3.36
  • PHP 8.2:8.2.35

5. 使用托管服务?如果你用的是托管 WordPress 主机或 PaaS,请查看他们的状态页或更新日志,看有没有关于 PHP2Shell 的通知。大多数会替你打补丁,但“大多数”不等于“全部”,而自己管理的 VPS 则完全要靠你自己。

如何修复

先打补丁,再重启。更新 PHP 是唯一完整的修复方法。

重启很重要:运行中的 worker 在被替换之前会一直把旧代码保留在内存中。如果用 Docker,请基于更新后的基础镜像(例如当前的 php:8.3-fpm 标签)重新构建并重新部署。不要只是重启旧容器。

在使用 PHP-FPM 的 Debian 或 Ubuntu 上,通常类似这样:

sudo apt update && sudo apt install --only-upgrade 'php8.3*'
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2   # if you use mod_php

如果今天无法打补丁,Qualys 总结了 PHP 官方的临时缓解措施。它们能降低风险,但不能让未打补丁的服务器变得安全。请在 php.ini 或 FPM 池配置中设置(不要用 .user.ini 或 ini_set),然后重启所有 worker。

如果某个服务尚未打补丁且不需要公开访问,请把它放到 VPN 或 IP 白名单之后,或者在能更新之前先下线。

; php.ini or FPM pool config (not .user.ini or ini_set)
session.upload_progress.enabled = 0
post_max_size = 8M          ; 32M if you need uploads
upload_max_filesize = 6M    ; keep below post_max_size

如果你用的是 PHP 8.1 或更旧的版本,现在就规划升级。部分旧分支有有限的回移植修复,但每次出现这类漏洞时,你都只能靠运气。

查找入侵迹象。检查是否有异常进程、Web 根目录中的新文件、陌生的 cron 任务以及从 Web 服务器发出的外连。Arctic Wolf 还指出,日志中许多“PHP2Shell”请求复用的是较旧的技术,所以一条看起来吓人的日志并不一定意味着入侵成功。

如果曾经暴露,请轮换机密。由于 CVE-2026-109619 可能泄露 worker 内存,凡是经过未打补丁、面向互联网的 PHP 进程的机密,都应视为可能已被看到。这包括数据库密码、API 密钥、会话签名密钥和支付服务商密钥。Laravel 等框架把这些保存在 .env 中,所以还要确认这个文件从来没有能通过 Web 访问。

暴露的 .env 文件:如何检测

快速检查清单

对你拥有的每个域名逐项检查:

  • 你拥有的每个域名和子域名都已列出,包括旧的营销网站和预发布网站。
  • 你知道哪些运行 PHP,以及实际处理 Web 请求的确切版本。
  • 每一个都已升级到 8.5.12、8.4.27、8.3.36、8.2.35 或厂商已修补的版本。
  • 更新后已重启 PHP worker 和 Web 服务器。
  • 任何尚未打补丁的服务都已限制访问或下线,并应用了缓解措施。
  • 暴露主机上的机密已经轮换。
  • 生产环境不再公开 PHP 版本,也不再显示堆栈跟踪。

更大的教训

PHP2Shell 会在几周内被修补并被遗忘,但这种模式不会。从“修复发布”到“被利用”的间隔如今只有几天,有时甚至是负数。小团队靠英雄主义是跑不赢的。真正有效的是清楚自己在运行什么,并在其中有东西发生变化时迅速察觉。

这和我们的 AI 应用上线检查清单背后的思路一样:现实中的大多数安全事件都源于容易检查的问题——前提是你真的去检查。

AppSafe 从外部扫描你的线上网站,就像攻击者看到的那样。它会查找缺失的安全头、泄露技术栈的 X-Powered-By 头、暴露的文件和详细错误等问题,并给出通俗易懂的修复方法。打完补丁后,对你的每个域名运行一次免费扫描,顺手把其他容易解决的问题也一并处理掉。

自动跑一遍这份清单

一次免费扫描即可检查你的应用是否存在所有这些问题,并为每个发现的问题给出一条 AI 修复提示词。

免费扫描我的应用