187 万台 PHP 服务器挂在公网上,22 万台跑着官方不修的版本

导语:PHP2Shell 的补丁发布两天后,安全研究员 Md Ismail Šojal(0x0SojalSec)用 Shodan 指纹做了一次全球普查:http.component:"php" 命中 1,877,436 台,按版本收窄后仍有 224,323 台在跑老版本。这个数字之所以刺眼,是因为按 PHP 官方和 Google Cloud 的说法,8.1 及更早的分支根本不发布修复补丁——这 22 万台,正好是 PHP2Shell 最无处可躲的那一批。


一、这份普查是怎么做的

先说方法,因为方法决定了这份数字能信到什么程度。

研究员用的是 Shodan 的搜索语法,公开列了八条查询:

http.component:"php"
"X-Powered-By: PHP"
http.component:"php" country:"xx"
"X-Powered-By: PHP/7.4.33"
"X-Powered-By: PHP/7.4"
"X-Powered-By: PHP/8."
http.component:"php" http.component_version:"7.4"
"X-Powered-By: PHP/8.1" country:"xx"

核心抓手有两个:一是 Shodan 自己解析 HTTP 响应头得到的 http.component 字段,二是 PHP 默认会在响应头里回一句 X-Powered-By: PHP/版本号。后者等于 PHP 服务器主动对外广播自己的精确版本。

我没法独立复现这些计数——Shodan 的搜索接口要 API key,公开页面也不回吐总数。所以下面的数字,我按研究员的原始截图引用。但截图本身是完整的 Shodan 界面,可信度不低:

Shodan 搜索 http.component:

图:Shodan 上 http.component:"php" 的搜索结果,截图来源为研究员原推,TOTAL RESULTS 1,877,436

而按版本收窄之后,查询量掉到二十二万:

Shodan 按 PHP 版本收窄后的搜索结果

图:Shodan 上按 PHP 7.4 版本收窄的搜索结果,截图来源为研究员原推,TOTAL RESULTS 224,323

这里必须加一句:187 万是下限,不是总量。 Shodan 只能扫到它扫到的机器。藏在内网后面的、走 CDN 的、只对特定来源开放连接的、主机名解析到私有段的,一个都进不来这个池子。而反向也成立——很多主机上跑的是同一台物理机上的虚拟站点,Shodan 记一条,真实站点可能十几个。

二、地理分布:香港在 7.4 榜单上排第二

先看全量 PHP 的国别分布:

排名国家/地区数量占 187.7 万比例
1美国510,82527.2%
2德国123,5566.6%
3日本95,7665.1%
4印度尼西亚89,4464.8%
5荷兰62,9253.4%

再看 PHP 7.4 的版本榜:

排名国家/地区数量占 22.4 万比例
1美国68,36330.5%
2香港20,6039.2%
3德国15,9447.1%
4日本15,8737.1%
5中国9,7064.3%

两个值得单说的点。

第一,老版本集中在特定区域,而不是均匀分布。 香港在 PHP 7.4 这一档里冲到第二,占到 22.4 万的 9.2%——它在全球 PHP 总量里排不进前五,在老版本榜上却是第二。这种倒挂通常意味着某个托管商、某个虚拟主机套餐或者一批批量部署的镜像,把整批机器锁在了老版本上,而不是零散的个人站长没升级。

第二,美国占了三分之一。 510,825 台 PHP 服务器、68,363 台 PHP 7.4。考虑到美国是全球云主机和虚拟主机保有量最大的市场,这个数字本身不算意外,但它意味着——这次事件的主要受害人群是英语世界的中小站长和开发者,而他们大多不会读中文安全公告。

顺带说一句,问卷里那些 country:"xx" 是研究员自己打的码,把具体国家筛掉了。所以完整国别分布我们看不到,只知道他筛过。

三、最要命的一层:这 22 万正好落在”官方不发修复”的那一档

PHP2Shell 的两个 CVE(CVE-2026-109618 和 CVE-2026-109619,GHSA 编号分别是 GHSA-w8hw-w9fx-j79w 和 GHSA-6wmf-4rv5-p3rp)都是 CVSS v4.0 9.2 分。10 月 21 日 13:30 UTC 官方发布了修复版本,一共四个:

分支首个修复版本
8.28.2.35
8.38.3.36
8.48.4.27
8.58.5.12

注意这张表的边界——它从 8.2 开始。

php2shell.com 官方专题站的”Upgrade PHP”表格里,只有这四行。8.1、8.0、7.4 都没有”First fixed release”这一栏。

这不是表格漏了。Google Cloud 的响应写得很直白:

Not patched: The PHP project is not releasing fixes for PHP 8.1 or earlier, which have reached end of life. …Applications on PHP 5.5, PHP 7.2, PHP 7.3, PHP 7.4, or PHP 8.1 remain vulnerable and must be upgraded to PHP 8.2 or newer.

欧盟 CERT 的公告口径一致,把受影响范围列成四条官方分支加上 “End-of-life branches (PHP 8.1 and older), which no longer receive updates from the PHP project”,并且明确写了一句:

Because of the severity, the PHP security team has also published minimal source backports for PHP 7.4, 8.0 and 8.1 for organisations that build from source or have no LTS vendor.

最小源码回移植,不是发行版二进制补丁。 意思是你得自己从源码编译 PHP 并打上这几个补丁。对绝大多数站长来说,这不叫”修复方案”,这叫”重新造一遍你的运行环境”。

真正能落地的路只有两条:

第一条,走 LTS 厂商或发行版的重建包。 Plesk 是典型例子——它的公告写得很清楚,7.4.33、8.0.30、8.1.34 这三个 EOL 版本”have the same version number, but different build date”,也就是同版本号、不同构建日期的重建包。cPanel 那边也放出了 ea-php74 及以上的更新。所以如果你用的是带面板的托管环境,去看你面板的更新通道,那里有货。

第二条,升到 8.2 及以上。 这是唯一能一劳永逸的方案,因为 8.2 之后的每个分支都有官方修复版本,而且 8.2 现在还在维护期内。

W3Techs 10 月 22 日的统计可以作为另一个口径的交叉验证:所有用 PHP 的网站里,PHP 8 系占 65.3%,PHP 7 系占 26.9%,PHP 5 系占 7.7%,PHP 4 系占 0.1%。也就是说,按流量加权的顶级网站里,还有超过四分之一跑在 PHP 7 上——而 PHP 7 已经整体 EOL。

Shodan 口径(公网可直连机器)和 W3Techs 口径(按流量统计的网站)本来就不该对上,但两个都指向同一个方向:PHP 7 是个正在腐烂的大山,而腐烂的那部分正好暴露在公网上。

四、X-Powered-By 是把刀递给扫描器

回到普查方法本身。有个细节值得所有站长抄在墙上:

你服务器返回的每一个 HTTP 响应里,PHP 都会加一句 X-Powered-By: PHP/7.4.33。 Shodan 的扫描器扫到这句,就知道你的精确版本、精确补丁版本,然后自动归类、生成指纹、写进数据库。攻击者用同一套查询,秒秒钟筛出”跑 7.4.33 的机器”,连指纹识别阶段都省了。

而 PHP 官方在 php2shell.com 的”Hardening after upgrading”一节里,恰恰列着这条建议:

Consider expose_php = 0 to reduce PHP version disclosure.

这就是全文最讽刺的一处:官方教你怎么把头号资产从扫描器的普查名单里摘掉,而这份普查本身,正是靠头号资产自己广播出来的。

对防守方来说这是好事——expose_php = 0 之后,你的机器从 187 万里消失了,扫描器挑不出你。

但反过来看攻击面,结论就不那么轻松了:关掉 expose_php 的机器,同样也从这份 187 万的名单里消失了。 也就是说,这份普查统计的是”愿意自报家门”的 PHP 服务器,真正的暴露面比 187 万要大,而大多少,取决于有多少人已经关掉了这个开关。 187 万这个数字既不是上限也不是下限,它是一个带着自我筛选偏差的样本。

至于说关掉就安全了——那是另一回事。漏洞在运行时,不在响应头里。

五、PoC 已经在流通了

欧盟 CERT 在公告里写了一句:

Technical details are now being discussed publicly, and initial proofs of concept (PoCs) have begun to circulate. This raises the likelihood that attackers are already exploiting the vulnerabilities.

时间线摆开:10 月 21 日 13:30 UTC 官方发布修复,同一天技术细节开始公开讨论,PoC 开始流通,Cloudflare 的 WAF 规则在当天 03:02 UTC 上线,GitHub advisory 在 13:34 UTC 出现,AlmaLinux 的包在 21:15 UTC 进了生产。

研究者做这份 Shodan 普查的时间是 10 月 22 日 10:46 UTC——PoC 流通之后第二天。

这个顺序意味着,普查报告还没发出来,攻击面就已经不是纸面数字了。而 CERT-EU 给出的处置建议里还有一条不常见的措辞:

CERT-EU advises organisations to patch affected assets immediately. Where that is not feasible, organisations should consider isolating internet-facing applications from public networks until a fix is applied and verified.

把面向互联网的应用直接隔离掉。这话很难听,但从一个欧盟政府 CERT 的嘴里说出来,分量不一样。

六、按你的身份对号入座

如果你跑的是 PHP 8.2 及以上 → 直接升到 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 里的对应版本,重启 Apache、PHP-FPM 和所有常驻 worker。官方原话是”这是唯一的完整修复”,并且强调 “Updating an application does not update the PHP runtime beneath it”——更新 WordPress 不等于更新了底下的 PHP。

如果你跑的是 PHP 7.4 / 8.0 / 8.1 → 优先找你所在托管环境的 LTS 厂商要重建包(Plesk、cPanel 这类已经放出来了),或者直接升到 8.2。除非你确实有能力自己编译带回移植的源码,否则不要指望”minimal source backport”这条官方后路。

如果你跑的是 PHP 5.x / 7.2 / 7.3 → 别修了,Google Cloud 的话是 “must be upgraded to PHP 8.2 or newer”。迁移工程量再大,也小于被未授权 RCE 的代价。

不管你是哪个版本,升级之前先做这几件事(都是 php2shell.com 官方列的):

  • memory_limit = -1 可以挡掉部分依赖内存上限处理的利用路径,但代价是把内存耗尽处理权交给操作系统,worker 可能被杀、请求被打断。官方建议配合 cgroup v2 的 memory.max 兜底
  • 不要用 RLIMIT_AS 或 RLIMIT_DATA 替代 memory_limit,PHP 官方警告这样会触发同样的脆弱失败路径
  • session.upload_progress.enabled = 0、post_max_size 压低、max_input_nesting_level 压低、display_errors = 0、fatal_error_backtraces = 0、降低 pm.max_requests 减少 worker 复用
  • expose_php = 0

如果你是厂商或托管商 → CERT-EU 建议查 NCSC-NL 的 GitHub 仓库,那里有一份第三方软件内嵌 PHP 的清单,因为大量商业和开源产品用 PHP 做后端,就算自己不暴露 PHP 安装也可能中招。

如果你是安全团队做资产盘点 → 用上面那几条 Shodan 查询语法对着自己的公网资产跑一遍。特别是注意托管在别人机器上的 PHP:你的域名指向一台共享主机,PHP 版本不是你能选的。Plesk、cPanel 这类面板的重建包能救你,但那得面板供应商推给你。

七、总结

这次 PHP2Shell 事件里,最难回答的问题不是”漏洞有多严重”,而是”到底有多少人会被打中”。

现在有第一个量化答案了:公网上 187 万台 PHP 服务器清晰可见,其中 22 万台跑着官方不打算修的分支。而这份名单还带着自我筛选偏差——那些关掉了 expose_php 的机器不在这份统计里,但它们的漏洞一点没少。

这件事真正的失败点有两层。 上面一层是 PHP 官方:EOL 分支不发二进制补丁,只留一句”最小源码回移植”,把编译运行环境的活儿推给了使用者。下面一层是托管生态:真正能救 7.4 用户的,是 Plesk 和 cPanel 那些愿意做重建包的面板厂商——是他们在替一个已经宣布放弃的分支兜底。

而 Shodan 这份普查的意义在于,它把”应该升级”这句话变成了”22 万台”。当一个数字大到具体,每个还在用 7.4 的站长才真正知道自己站在什么地方。

顺便给所有还在跑老版本的 PHP 站点提个醒:官方还提过一句”更新应用不等于更新底下的 PHP 运行时”,这句话跟版本没关系,跟你用什么框架、什么 CMS、什么面板也都没关系。你今天装的每一个新版本 WordPress,跑的还是那块 7.4.33。


素材出处:Shodan 搜索结果截图(研究员原推)|php2shell.com 官方专题站 Upgrade PHP 与 Hardening 章节|CERT-EU 安全公告 2026-018|Google Cloud 官方响应公告|Plesk 与 cPanel 官方支持文档|PHP Foundation、CVE-2026-109618 / GHSA-w8hw-w9fx-j79w、CVE-2026-109619 / GHSA-6wmf-4rv5-p3rp|W3Techs PHP 版本统计(2026-10-22)

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容