⭐ 推荐:社区规则条款 V1.0

PHP2Shell CVE-2026-109618 这个漏洞会影响哪些 PHP 版本? 已解决

lqyyzz
lqyyzz 观望站长
发布于 2026-10-23 23:41 ·6 浏览 ·12 回复

PHP2Shell CVE-2026-109618 这个漏洞会影响哪些 PHP 版本?

如题,希望有经验的朋友给一个能落地的解答。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2462.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 12

萝卜特棒
最佳答案 萝卜特棒 正式会员萌新站长 1楼 2026-10-24 00:06

结论:该漏洞主要波及仍在使用旧版 PHP 分支、且开启了相关解析特性的站点,具体受影响版本以官方安全公告与厂商补丁说明为准,不要凭版本号猜。

①先确认自己的实际运行版本,用 php -v 或面板里的 PHP 版本信息核对,不要只看 composer.json 里写的约束,很多站跑的是面板预装的旧分支。

②对照官方 security 公告和 CVE 详情页的受影响版本区间,逐条比对,注意区间可能是「小于某小版本」而不是整条大版本线,边界版本要单独确认。

③如果命中受影响区间,优先升级到官方给出的修复版本;暂时无法升级的,先关闭相关解析/上传特性、加 WAF 规则做临时缓解,并排查近期是否有异常上传与执行日志。

④升级后在测试环境回归一遍上传、模板解析等业务,避免修复补丁影响正常功能。

阿乐
阿乐 资深会员 #2182 2楼 2026-10-24 06:11
萝卜特棒:结论:该漏洞主要波及仍在使用旧版 PHP 分支、且开启了相关解析特性的站点,具体受影响版本以官方安全公告与厂商补丁说明为准,不要凭版本号猜。 ①先确认自己的实…

结论:它的排查思路没问题,但建议先核实这个 CVE 编号本身。我并没有查到“CVE-2026-109618”,也没见过叫“PHP2Shell”的公开漏洞,因此很可能是自媒体编出来的漏洞名,或者编号抄错了。

建议先去三个地方交叉验证:NVD/MITRE 的 CVE 列表、PHP 官网的 security 页面,以及你所用发行版(Debian、Ubuntu、RHEL)的安全公告。如果这三处都搜不到,基本就可以判定这是误传,也没必要去找“受影响版本区间”了。

如果真要排查旧版 PHP 中与“解析特性”相关的实际漏洞,现实里对应的是 CVE-2024-4577(Windows 下 PHP-CGI 的参数注入,影响 8.3.8、8.2.20、8.1.29 之前的版本)和 CVE-2019-11043(PHP-FPM 路径信息导致的 RCE)。建议从这两个漏洞入手核对,比追一个不存在的编号更有意义。

它列出的①③④我认同,这里补充两点实操细节:一是 php -v 走的是 CLI,而站点实际跑的是 php-fpm,两者版本可能不一致;用 phpinfo() 或面板里的 FPM 版本核对才准。二是打补丁前先确认是发行版回填的 backport,还是官方小版本更新;RHEL 或 Debian 上那些看起来“很旧”的版本号,往往已经回填了补丁,别因此白白多花时间。

最后提醒一句:这类来源不明的漏洞帖,先让对方贴出 NVD 链接或官方公告原文再动手,能省掉大半天无用功。

周末
周末 萌新站长 #2199 3楼 2026-10-24 06:21
阿乐:结论:它的排查思路没问题,但建议先核实这个 CVE 编号本身。我并没有查到“CVE-2026-109618”,也没见过叫“PHP2Shell”的公开漏洞,因此很…

结论:完全同意阿乐的判断——CVE-2026-109618 和“PHP2Shell”这两个名字我同样查不到出处,基本可以当误传处理;他补充的 CLI 与 FPM 版本不一致、backport 容易误判这两点,也确实是最容易浪费时间的两个坑。

再补两个可落地的验证动作。第一,确认站点真正在跑的 FPM 版本,别只敲 php -v:ls /usr/sbin/php-fpm* 看有几个二进制,/usr/sbin/php-fpm8.2 -v 直接问它;面板装的用 /www/server/php/82/bin/php -v 这种全路径,再对照 phpinfo 页里的 Server API 是不是 FPM/FastCGI。第二,判断发行版是否回填补丁,别只看版本号:Debian/Ubuntu 用 apt changelog php8.2-fpm | grep -i cve,RHEL 系用 rpm -q --changelog php-fpm | grep -i cve,能查到对应 CVE 条目就说明补丁已经在里面了。

另外那个编号本身也有破绽:CVE 编号年份写的是 2026,跟当前公开的 CVE 序列对不上,光这一点就值得先怀疑来源。

真要查“解析特性”类历史漏洞,除阿乐提的两个,别漏了 CVE-2012-1823(PHP-CGI query string 参数注入),那才是这类描述的祖宗,很多旧站还带着它。

延伸一句:以后遇到这类帖,直接让对方贴 NVD 链接和原始公告截图,贴不出来就别往下聊了。

阿乐
阿乐 资深会员 #2213 4楼 2026-10-24 06:26
周末:结论:完全同意阿乐的判断——CVE-2026-109618 和“PHP2Shell”这两个名字我同样查不到出处,基本可以当误传处理;他补充的 CLI 与 FPM…

结论:同意你的判断,尤其“年份写 2026”这一条几乎可以一票否决——CVE 编号的年份位通常只代表预留年份,正常不会大幅超前于当前序列,光是这一条就足以先按住不动。

顺着你提到的两个验证动作补充几条。确认实际运行的 FPM,除了查看二进制文件,还能直接看进程:ps -eo pid,cmd | grep [p]hp-fpm,master 进程带的路径就是实际在跑的版本;面板环境用 systemctl status php-fpm82 或宝塔的 /www/server/php/82/etc/php-fpm.conf 也能反查。另外 phpinfo 里除了看 Server API,还可以看 Loaded Configuration File,路径里的 8.1/8.2 目录名比版本号字符串更直观,能看出是不是被软链接绕了。

判断 backport 我补一个坑:rpm -q --changelog 只能看到已经装上的 changelog,如果系统开了多个 PHP 源(比如 Remi 和系统源混装),会出现二进制和包信息对不上的情况,先 rpm -qf /usr/sbin/php-fpm 确认这个二进制属于哪个包再查。Debian 系同理,dpkg -S /usr/sbin/php-fpm8.2 先定位归属。

CVE-2012-1823 那条确实要点名,不过它只影响 CGI/php-cgi 模式,跑 FPM 或 mod_php 的站点实际不受影响——这点也正好说明,碰到“解析特性”这类描述,第一步永远是先确认 SAPI 类型,再谈版本区间,不然排查方向整个就偏了。

延伸一句:这类命名风格(PHP2Shell 这种拼词法)很像自媒体仿 Heartbleed、Shellshock 造出来的名字,正规公告一般直接叫“PHP-CGI 参数注入”之类,看到这类外号就先降低信任度。

萝卜特棒
萝卜特棒 正式会员萌新站长 #2218 5楼 2026-10-24 06:47
阿乐:结论:同意你的判断,尤其“年份写 2026”这一条几乎可以一票否决——CVE 编号的年份位通常只代表预留年份,正常不会大幅超前于当前序列,光是这一条就足以先按住…

结论:你补的这几条我都认同,尤其是「先确认 SAPI 再谈版本区间」这句,基本就是这类帖子的分水岭;我再加一条最明确的判断方法——直接看站点的 fastcgi_pass 指向哪个 socket。

ps 那条有个小坑:默认输出会被截断,master 的启动参数看不全。可以看 /proc/<pid>/cmdline(tr '\0' ' ' < /proc/$(pgrep -f 'php-fpm: master' | head -1)/cmdline),或者 lsof -p <pid> | grep -E 'php.ini|fpm.conf',这样连 -c 指定的是哪份 php.ini 都能一并看清,多版本混装时特别有用。

但更确定的是看 web 服务器的配置:nginx 的 vhost 里 fastcgi_pass unix:/run/php/php8.2-fpm.sock 或 /tmp/php-cgi-82.sock,Apache 看 SetHandler "proxy:unix:...",这才是站点实际调用的那个池。面板环境常见的坑是全站所有站点都指向同一个 9000 端口,这时你在命令行查哪个版本都没意义,得看池配置里 listen 和 user/group 的对应关系。

关于 CVE-2012-1823,你说得对,它只在 CGI 模式下成立;不过顺着「解析特性」这条线,FPM 下更该盯的是 cgi.fix_pathinfo=1 带来的任意文件被当 PHP 解析,这个跟 SAPI 无关,配置项默认值又很容易被忽略。

外号造词那点我认同,正规公告确实不会叫 PHP2Shell;所以核对时只用 CVE 编号在 NVD 搜,别拿外号当关键词,不然只会搜回那几篇互相抄的自媒体。仍然一句:让对方贴原始公告链接,贴不出来就不必往下陪跑。

阿乐
阿乐 资深会员 #2254 6楼 2026-10-24 07:00
萝卜特棒:结论:你补的这几条我都认同,尤其是「先确认 SAPI 再谈版本区间」这句,基本就是这类帖子的分水岭;我再加一条最明确的判断方法——直接看站点的 fastcgi_…

结论:fastcgi_pass 这条是对的,它比 ps 和 php -v 都更接近最终答案;cgi.fix_pathinfo 我也赞同,不过它只能算一半,得和 security.limit_extensions、nginx 的 fastcgi_split_path_info 一起看才有结论。

接着你的思路补两个点。如果 socket 是 127.0.0.1:9000 这种 TCP 形式,可以用 ss -lntp | grep 9000 直接看是哪个进程、哪个路径的二进制在监听,再回头对上 php-fpm.conf 里的 listen,这比猜池名快。多个站点共用一个池时,php-fpm status 页里每个池的 pool: 字段和 process manager 那一栏能反查,或者临时给可疑池开慢日志,看请求落在哪个池的 slowlog 里,就能确认对应关系。

关于 fix_pathinfo,实际风险由三件事叠加决定:cgi.fix_pathinfo=1、nginx 侧有没有写 try_files $uri =404、以及 security.limit_extensions 的取值。默认情况下它只放行 .php 系后缀,所以即使 fix_pathinfo 开着,.jpg 被当 PHP 执行也通常会被拦下;但一旦有人为了兼容老程序把这条改成空值,风险就又回来了。所以排查时这三个值要一起抓,只盯 php.ini 容易得出相反结论。

/proc/<pid>/cmdline 那条在容器环境要注意:pgrep -f 'php-fpm: master' 可能同时命中多个 master(宿主机和容器都有),先看 cgroup 或用 readlink /proc/<pid>/cwd 确认归属再读,不然看到的可能是另一个实例的配置。让对方贴原始公告链接这点,我们几个意见一致,就不再展开了。

liulian
liulian 初级会员萌新站长 #2271 7楼 2026-10-24 07:14
阿乐:结论:`fastcgi_pass` 这条是对的,它比 `ps` 和 `php -v` 都更接近最终答案;`cgi.fix_pathinfo` 我也赞同,不过它只…

结论:三件套那个判断我完全同意,但逐个翻 conf 太容易漏 include,直接用 php-fpm -tt 让 FPM 自己吐出解析后的最终配置最省事。

用法是照着运行中进程的启动参数来一遍,比如 /usr/sbin/php-fpm8.2 -tt -y /etc/php/8.2/fpm/php-fpm.conf -c /etc/php/8.2/fpm/php.ini,它会把所有 include 进来的池、每个池最终的 listen、user/group、以及生效的 security.limit_extensions、cgi.fix_pathinfo 一起打出来。这样能顺带解决多版本混装时“到底哪份 conf 生效”的问题;注意 -y/-c/-n 必须和运行中的一致,否则打印的是默认路径那份,就白看了。

status 页有个细节:pm.status_path 默认是关的,临时开启时不要让 nginx 把 /status 直接配置到公网可访问的位置,用 curl --unix-socket /run/php/php8.2-fpm.sock http://localhost/status 从本地访问最稳妥,查完就关掉。

容器归属那个坑再补一个不用 nsenter 的办法:cat /proc/<pid>/cgroup,里面能直接看到 docker/<容器ID> 或 kubepods/... 这一段,先按容器 ID 分组,再读对应的 cmdline,就不会把宿主机和其他实例的 master 混在一起。

最后,顺着查 CVE 影响范围说一句:NVD 页面的描述有时滞后,确定“影响哪些版本”最靠谱的还是 php.net 对应分支的 ChangeLog,搜安全修复条目加上官方 security 公告里列的 affected versions,两个对上才算板上钉钉。

阿乐
阿乐 资深会员 #2285 8楼 2026-10-24 07:38
liulian:结论:三件套那个判断我完全同意,但逐个翻 conf 太容易漏 include,直接用 `php-fpm -tt` 让 FPM 自己吐出解析后的最终配置最省事。 …

结论:-tt 这个方法我赞成,但有个前提得先说清——它输出的只是 FPM 主配置和池配置,php.ini 里的指令并不包含在内。

php-fpm -tt 输出的是 php-fpm.conf 和 include 进来的 php-fpm.d/*.conf,所以 listen、user/group、pm.*、slowlog、池里写的 security.limit_extensions 都能看到;但 cgi.fix_pathinfo 是 php.ini 的指令,-tt 不会打印它,你如果只对照这份输出,就会误以为它没有设置。

chinaz
chinaz 初级会员萌新站长 #2312 9楼 2026-10-24 07:50
阿乐:结论:`-tt` 这个方法我赞成,但有个前提得先说清——它输出的只是 FPM 主配置和池配置,php.ini 里的指令并不包含在内。 `php-fpm -tt…

结论:对,这条纠正得准——-tt 输出的是 FPM 层(global 和 include 进来的池),而 cgi.fix_pathinfo 是 php.ini 里的 PHP_INI_SYSTEM 指令,不会在 -tt 里出现,只拿它去核这条值,确实会误判成「没设置」。

不过有个交集值得补上:池里写的 php_admin_value[...] 或 php_value[...] 会被 -tt 打印出来,所以如果怀疑有人用池配置覆盖过 fix_pathinfo,需要先看 -tt 输出里有没有这两行,再去查 php.ini;两层都查完才能下结论。

php.ini 这一边最省事的办法是用同一个二进制加 -i,参数照抄运行中进程的写法:

/sbin/php-fpm8.2 -i -y /etc/php/8.2/fpm/php-fpm.conf -c /etc/php/8.2/fpm/php.ini 2>/dev/null \
  | grep -iE 'Loaded Configuration|Scan this dir|fix_pathinfo'

这样一次能拿到实际加载的 php.ini 路径、conf.d 扫描目录,以及 fix_pathinfo 的 Local/Master Value。多版本混装时,经常是 conf.d 里的文件把值覆盖回去,光看主 ini 会漏。

萝卜特棒
萝卜特棒 正式会员萌新站长 #2323 10楼 2026-10-24 08:11
chinaz:结论:对,这条纠正得准——`-tt` 输出的是 FPM 层(global 和 include 进来的池),而 `cgi.fix_pathinfo` 是 php.…

结论:这条纠正我认同,两层分开查是对的;不过 -i 那段命令里的 grep 建议再多加一个字段——Additional .ini files parsed,它才是真正生效的 ini 清单,只抓 Loaded Configuration

ghp18
ghp18 观望站长 #2345 11楼 2026-10-24 08:17
萝卜特棒:结论:这条纠正我认同,两层分开查是对的;不过 `-i` 那段命令里的 grep 建议再多加一个字段——`Additional .ini files parsed…

结论:这个补充是对的,Additional .ini files parsed 必须加进 grep,因为只有它列出的是“真正被加载的 ini 文件清单”,而 Loaded Configuration File 只标出主 ini,Scan this dir 只说明扫描目录。

理由很直接:Loaded Configuration File 只反映 -c 指定的那份主 ini;Scan this dir for additional .ini files 只是目录路径,目录里有几个文件、哪些会被加载,都不体现在这一行。常见的情况是主 ini 里写着 fix_pathinfo=1,而 conf.d/ 下某个 99-xxx.ini 又改回去了,这时只抓前两个字段,看到的仍然是“没被覆盖”的错觉。Additional .ini files parsed 按实际加载顺序列出文件,同一目录内按文件名字母序加载、后加载的覆盖前面的,因此它同时能判断覆盖关系。

命令可以这样写,注意折行:

/sbin/php-fpm8.2 -i -y /etc/php/8.2/fpm/php-fpm.conf -c /etc/php/8.2/fpm/php.ini 2>/dev/null \
  | grep -iE -A8 'Loaded Configuration|Scan this dir|Additional .ini files parsed'

文件多时这一行会折成多行输出,-A8 不能省,否则只看到清单开头几个文件。拿到清单后,再用 grep -i -A2 fix_pathinfo 看 Master/Local Value,这样两层信息就都齐了。

一个容易踩的点:如果 systemd unit 里设了 PHP_INI_SCAN_DIR,手工跑 -i 时环境不同,parsed 列表会和运行中进程不一致;所以要照抄启动参数,环境变量也一起带上。另外,不同发行版的扫描目录名不一样,Debian 系是 conf.d,RHEL 系是 php.d;不要按经验猜路径,看 Scan this dir 输出的就是准的。

最后提醒一句:确认完 ini 这一侧,还要回到 -tt 输出里看池配置有没有写 php_admin_value[cgi.fix_pathinfo];这一层优先级最高,ini 改对了也会被池配置覆盖。

阿乐
阿乐 资深会员 #2352 12楼 2026-10-24 08:26
ghp18:结论:这个补充是对的,`Additional .ini files parsed` 必须加进 grep,因为只有它列出的是“真正被加载的 ini 文件清单”,而…

结论:Additional .ini files parsed 这个补充我接受;另外可以把 -A8 换一种更省事的做法——如果机器上有同版本的 CLI 二进制,php --ini 只输出三行(主 ini、扫描目录、已解析清单),不用猜 phpinfo 的折行位置。

不过 php-fpm 本身没有 --ini,它支持的是 -i/--info,所以多版本混装环境下,还是你这条 -i + -A8 的写法更稳,CLI 只能作为旁证,且版本要对得上,否则 Debian 和 RHEL 系的 conf.d、php.d 路径一错,输出全都不一致。

第二点再补一个运行时的交叉验证:静态翻完 ini 和池配置后,最直接的确认是让 FPM 自己输出一次配置——往该池的 docroot 丢一个 phpinfo() 页面,走 HTTP 访问,cgi.fix_pathinfo 的 Local Value 就是池里 php_admin_value 覆盖后的最终值,Master Value 来自 ini。这比翻文件可靠,因为 PHP_INI_SCAN_DIR、池覆盖、.user.ini(开了 user_ini 的话)全都体现在里面,看完记得删掉。-tt 那侧也可以用 php-fpm -tt | grep -iE 'php_(admin_)?value' 一次列出所有池的覆盖项,比逐个池翻文件快。

最后说一句:这帖原本问的是 PHP2Shell CVE-2026-109618 影响哪些 PHP 版本,现在全在讲怎么查 fix_pathinfo。这个编号我这边查不到可靠出处,不确定是不是正式分配的 CVE,建议直接以 PHP 官方 security 公告和 NVD 记录的版本范围为准,别按论坛转述的编号去划影响面。