php2shell 公网扫描实录:两轮 PoC,和一次“补丁先到”的防守
2026-10-23 · 应急响应笔记
准备写php2shell在最新受影响的几个php版本+WordPress配置的默认条件下的RCE时我的AI运维告诉我今天被扫描了-_-, 谁这么无聊扫描我这个小破站啊
10-21 22:00,PHP 官方紧急发布补丁,修复 php2shell(CVE-2026-109618 / CVE-2026-109619,CVSS 4.0 9.2,影响 PHP 5.4~8.5,修复版 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12)。这个洞在应用代码执行之前触发、未认证 POST 即可尝试,公开 PoC 围绕 session.upload_progress 和上千个 multipart 分片做文章。按以往经验,PoC 公开后 24~48 小时公网扫描就会铺开——这次几乎没等。
时间线
- 10-21 23:00:连夜排查两个站点,日志零痕迹(关键词、POST 洪流、5xx、webshell 落地全部干净)。
- 10-22 20:15:两个 PHP 站点分别升级到 8.2.35 和 8.5.12,
upload_progress保持 Off。 - 10-23 06:30 / 11:18:两轮 PoC 扫描到来,全部被挡。
被扫成什么样
两波请求形态完全一致,第二波只是换了个 IP:
161.118.252.175 [23/Oct/2026:06:30:01 +0800] POST /index.php 200
UA: Mozilla/5.0 ... Chrome/60.0.3112.113 ... PHP2Shell/1.0.0
161.118.194.12 [23/Oct/2026:11:18:43 +0800] POST /index.php 200
UA: 同上,连 Chrome 版本都没改

每个 IP 各 3 发:2 发 200、1 发 413。两个 IP 同属 Oracle Cloud(AS31898,161.118.192.0/18),是同一套工具在换机器跑,不像两个独立团伙。
为什么没被打穿
- 补丁先到:扫描到来时两个站点已经是 8.2.35 / 8.5.12。
- 新护栏生效:进到 PHP 的请求,在请求启动阶段就被拦下,日志里留下明确证据:
PHP Warning: PHP Request Startup: Multipart body parts limit exceeded 1020.
To increase the limit change max_multipart_body_parts in php.ini.
PoC 想用上千个 multipart 分片触发内存破坏,8.2.35 新增的分片计数直接截断了这条路。
- 体积限制兜底:第三发请求体超过反代的限制,反代对请求体大小设了上限,超大包直接 413 ,连 PHP 都没碰到。
- 原始原语是关的:
session.upload_progress.enabled = Off一直没开;返回的 200 是 35KB(gzip 后)的普通首页,不是命令输出。
当天两个 PHP 站点的结果:重启 0 次、5xx 0 个、无 segfault / OOM,FPM 子进程零异常退出。
给同行的几条建议
- 补丁是唯一的解。关
upload_progress、加 WAF 规则都只是缓解——这个漏洞在应用代码之前触发,WAF 规则未必覆盖得到。 - 升级后别只看镜像 tag,用
php -v和php -i | grep max_multipart_body_parts确认版本与护栏真的生效。 - 反代的
client_max_body_size是低成本高收益的一层,普通博客 1m/3m/5m/10m 足够。 - 日志里盯三类信号:UA 带工具指纹(如
PHP2Shell/1.0.0)、异常大的 multipart POST、PHP 日志里的Multipart body parts limit exceeded。 - 别按“云厂商 = 可信”放行,Oracle Cloud、GCP、Azure 的低价实例是这类扫描的重灾区。
最后
这次能全身而退,一半是执行力(补丁赶在扫描前 10 小时落地),一半是纵深(体积限制 + 原语关闭 + 版本修复各挡一刀)。还在修复版以下的朋友,尽快升级;已经挨过扫的,先去 PHP-FPM 日志里搜 exited on signal 和 Multipart body parts limit exceeded——前者说明崩过,后者说明挡住了。


