作者:CGO时间: 26-10-23浏览次数: 16
一、事情是怎么发生的
10 月 22 日,PHP 官方安全公告集中披露了两个高危漏洞,社区把它们统称为“php2shell”——名字很直白:从一次精心构造的 HTTP 请求,最终在服务器上拿到一个可以执行命令的 WebShell。
这不是那种“需要用户配合点击”的漏洞。攻击者不需要账号,不需要密码,只要能访问到你的网站,就有一次发包的机会。对于用 PHP 搭建的企业官网、商城、CMS 后台来说,这属于“必须当天处理”的那一类安全事件。
二、两个 CVE 分别在干什么
CVE-2026-109619:会话上传进度机制被滥用(本次的重点)
PHP 有一个“上传进度”功能:用户往服务器传大文件时,PHP 会在会话(session)里写入进度信息,前端就能显示“已上传 60%”。问题出在这段进度数据的处理上——当上传请求携带的字段名与 session 指令前缀构造存在冲突时,写入 session 的内容可能被错误解析,进而造成代码执行。
好消息是:这个功能并不是网站运行必需的。绝大多数企业网站根本没有用到上传进度条,也就是说,关掉它几乎不影响业务,却能直接封住这条攻击路径。
CVE-2026-109618:恶意构造的 multipart 请求触发内存问题
这个漏洞的利用方式,是通过构造超深嵌套、超多的 multipart 表单字段,把 PHP 进程的内存吃穿,诱发内存耗尽(OOM)类的异常状态,为后续利用创造条件。它的攻击面来自“字段数量”和“嵌套深度”,因此收紧内存与 POST、上传、输入变量限制,就能显著提高触发门槛。
三、先花 3 分钟自查:我中招了吗
1. 看版本。 SSH 进入服务器执行 php -v;不方便进命令行的,可以临时放一个 phpinfo() 页面查看 PHP Version(看完立刻删除,别留着暴露环境信息)。
2. 看是否开启了上传进度。 在 phpinfo() 页面搜索 session.upload_progress.enabled,显示 On 的,就是 CVE-2026-109619 的受影响面。
3. 看运行方式。 确认是 php-fpm(Nginx 常见)、还是 Apache 的 mod_php、或是 LiteSpeed / CGI 模式,这决定了下面配置改完之后怎么重启才生效。
4. 看历史日志。 检查访问日志里有没有异常的大量 multipart POST 请求、来自陌生 IP 的短连接高频提交、以及在上传接口路径上出现的可疑参数名。
四、第一选择:升级到官方修复版本
任何临时配置都只是“争取时间”,真正的修复只有一条路:升级到官方修复版本。
请先核对当前大版本(5.x / 7.x / 8.x),再到 PHP 官方或对应发行版的软件源确认修复后的版本号,在测试环境验证业务正常后再上生产。升级前务必完整备份程序、数据库和 php.ini、
www.conf 等配置文件,确保可以回滚。
五、低版本暂时无法升级?用 php.ini 先把门关上
现实中,很多站点做不到“立刻升级”:老系统绑定了特定 PHP 版本、源码已经无人维护、或者正版程序商还没出兼容补丁。这种情况不要硬扛,可以先用配置层封堵把风险压下来。
以下配置可直接复制到 php.ini 中按你的实际情况修改(php.ini 通常位于 /etc/php/版本/fpm/php.ini,具体以 php --ini 输出为准):
; ========== 针对 CVE-2026-109619:关闭会话上传进度(重点) ==========
session.upload_progress.enabled = Off
session.upload_progress.cleanup = Off
session.upload_progress.prefix = ""
session.upload_progress.name = ""
; ========== 针对 CVE-2026-109618:收紧内存、POST、上传限制,提高触发门槛 ==========
; 不要盲目调大 memory_limit!攻击者目标就是触发OOM,合理压低
memory_limit = 64M
post_max_size = 8M
upload_max_filesize = 2M
max_file_uploads = 5
; 限制 multipart 字段数量,减少恶意嵌套字段攻击面
max_input_vars = 1000
max_input_nesting_level = 64
; 关闭危险 display_errors,避免错误信息泄露(辅助加固)
display_errors = Off
display_startup_errors = Off
; 关闭自动全局变量(老版本加固)
register_globals = Off
; 关闭cgi.fix_pathinfo(FPM环境经典加固)
cgi.fix_pathinfo = 0
如果是 php-fpm 运行环境,再在 FPM 配置文件(池配置 www.conf)里补上一条:
; ========== FPM配置文件 ==========
pm.max_requests = 200
这几行到底在做什么,逐条说明:
• 关闭 session.upload_progress 四项:直接从源头关闭上传进度功能,并清空其前缀与字段名,让 CVE-2026-109619 失去可利用的入口。这是本次临时封堵里最关键的一步。
• memory_limit = 64M:注意这里的方向感。很多人一看到内存类问题就习惯性把内存调大,这恰恰是攻击者希望看到的——进程越大,一次并发打穿全池的“收益”越高。合理压低反而能提高攻击成本。当然,如果你的业务确实需要更大内存(例如后台导出大报表),可以按实际用量适度上浮,但不要一上来就给到 512M、1G。
• post_max_size / upload_max_filesize / max_file_uploads:把单次请求体、单文件体积、并发上传文件数收在业务真正需要的范围内。企业官网通常 8M、2M、5 个足够;如果有大文件上传需求,单独给那个接口放开,别在 php.ini 里全站放宽。
• max_input_vars = 1000、max_input_nesting_level = 64:限制字段数量与嵌套层数,正是针对恶意嵌套 multipart 字段的攻击面。
• display_errors = Off:报错不再输出到页面,避免路径、SQL、组件版本等信息泄露给攻击者。错误排查请改看日志文件。
• register_globals = Off:PHP 老版本的历史遗留高危开关,能关就关(5.4 之后该指令已移除,写在配置里可能提示未知指令,删掉即可,不影响其他配置生效)。
• cgi.fix_pathinfo = 0:这是 php-fpm / Nginx 环境的经典加固项,防止 .php 被解析到不该解析的文件上,与本次封堵形成叠加防护。
• pm.max_requests = 200:让每个 FPM 子进程处理 200 个请求后自动重建,即使内存被缓慢吃掉或残留异常状态,也能快速回收,降低被持续压制的风险。
六、改完之后,别忘这两步
1. 重启服务才会生效。 改的是 fpm 的 php.ini,就要 systemctl restart php-fpm(或对应版本服务名);Apache mod_php 环境重启 httpd/apache2。只 reload Nginx 是没用的。
2. 验证配置真的生效了。 再看一次 phpinfo(),确认 session.upload_progress.enabled 为 Off、cgi.fix_pathinfo 为 0、memory_limit 与预期一致。没验证等于没改。
七、临时措施之外,还需要做这四件事
• 前置防护收口:在 WAF 或防火墙层面对上传类接口加频率限制,拦截字段数量异常、请求体畸形的 POST 请求;有条件的话临时只放通业务必需的路径。
• 权限最小化:网站运行账号不要给到 root,目录权限遵循“可写目录只有上传与缓存目录”的原则,重点检查上传目录的执行权限,能禁解析就禁掉。
• 排查是否已被入侵:重点看最近新增或修改时间的 .php 文件、模板目录里的可疑文件、计划任务(crontab)、被改写的 .user.ini 与 .htaccess。发现可疑文件先隔离留存证据,再清理。
• 数据兜底:处理前完成一次完整备份(程序 + 数据库 + 配置文件)。真出事时,能恢复比什么都重要。
八、几个容易踩的坑
误区一:改了配置就当“已经修好了”。 配置封堵只是缩小攻击面、抬高利用门槛,官方修复版本出来之后,依然要按计划在测试环境验证后升级。
误区二:一上来就把 memory_limit 调到最大。 前面说过了,这个方向是反的。
误区三:只改了 php.ini,忘了 php-fpm 的池配置。 pm.max_requests 属于池配置项,写在 php.ini 里不会生效,改的位置在 www.conf。
误区四:生产环境直接改,没有回滚方案。 收紧上传与 POST 限制后,个别“上传超大附件”的功能可能会报错,务必提前通知业务方并留好备份。
九、总结
“php2shell”这类远程代码执行漏洞的可怕之处,在于攻击门槛低、影响面广,而低版本 PHP 在企业站点里存量大、更新慢,正是最容易挨打的位置。正确姿势分三层:第一层立刻自查,确认版本与上传进度开关状态;第二层马上封堵,关闭 session.upload_progress、收紧内存与 POST/上传/输入变量限制、关闭 display_errors 与 cgi.fix_pathinfo,并补上 pm.max_requests = 200;第三层彻底修复,备份后升级到官方修复版本,再配合 WAF、最小权限与日常监控,把这类风险挡在下一次漏洞披露之前。
021-62260393
扫码添加好友