Papa Kuhikuhi ʻatikala
凌晨一点多,手机在枕边震了起来。
不是闹钟,是服务器的告警。
我翻了个身,眯着眼点开,心跳直接漏了一拍。
摸过笔记本连上服务器,翻了一会儿 nginx 的访问日志。
好家伙。
那一串请求路径,整整齐齐,全是在扫 PHP2Shell 的利用路径。
对方连账号密码都没试,就是纯粹的、赤裸的、工业化的扫描。
就像一个贼在门口挨个试锁芯,试完还在门上贴了张纸条,写着「今晚我还来」。
我一个激灵坐起来,衣服都没顾上穿。
那一刻脑子里只有一个念头。
今晚,别睡了。
那晚我干了三件事。
查日志,确认这波扫描是从几点开始的。
查版本,看自己到底在不在受影响名单里。
查备份,确认快照是新的,真出事能滚回去。
做完这些,窗外天还没亮,小区安静得能听见冰箱的声音。
我裹着毯子坐在显示器前,感觉自己像个守夜的。
守的不是别人,是自己几年前偷懒埋下的雷。
凌晨三点多,我挨个站点查 PHP 版本。
8.5.11.
8.5.11.
还是 8.5.11。
全都在受影响名单里躺着,一个没跑掉。
那感觉,就像考试前一晚才发现自己报错了科目。
后来你猜怎么着。
补丁打完,版本验完,我坐在一片黑漆漆的房间里,突然有点恍惚。
不是因为后怕。
是因为发现,自己跟服务器打了这么多年交道,居然还是会在一场凌晨的告警里手忙脚乱。
所以就有了这篇东西。
说真的,写这种带教程属性的文章,我一直是有心理负担的。
我也不是啥安全大佬,就是一个自己搭服务器、自己运维的普通开发者。
我能掏出来的,只是自己真实踩过的坑,和一套今晚就能照着做的动作。
不成熟,但保真。
你要是有更优雅的方案,当然以你的为准,我说的这套,主打一个笨,但有效。
丑话说在前面,以下所有操作,请务必先在快照备份之后再做。
别问我怎么知道的。
问就是曾经有一个不信邪的少年,在没有备份的情况下敲下了 upgrade。
那个人。
就是我。
先把这个漏洞说清楚,不然你敲命令心里都没底
先花几分钟说说这个漏洞本身。
不然你照着敲命令,心里没底,手也容易抖。
PHP 这玩意,跑着全球大概七成的网站。
你早上刷的新闻,你买的奶茶背后的小程序,多半都有它在出力。
它就是这么个随处可见、但你又基本感知不到的基础设施。
这次出事,藏在 PHP 的内存管理里。
worker 是啥呢,你可以理解成 PHP 雇来干活的工人。
一个工人干完一单,本该把桌面收拾干净,再接待下一单。
这回有些人没收拾,下一单的客人一上来,就捡到了上一单留下的东西。
攻击者要做的,就是故意把脏东西留在桌上,然后看着下一个请求踩进去。
有个全局状态没被正确重置,被同一个 worker 处理的后一个请求捡到了,攻击者就能顺着这条缝隙,把代码塞进去执行。
不需要账号,不需要密码,甚至不依赖你网站自己有没有漏洞。
只要 PHP 版本中招,一个再普通不过的请求打过去,对方就能拿到 Shell。
Shell 是啥呢。
你想想看,你家的门锁被撬了,对方不但进了屋,还顺手配了一把自己的钥匙。
从此进进出出,比你还熟。
官方给的 CVSS 评分是 9.2。
这分数什么水平呢。
满分 10 分,9.2 已经属于你可以放下手上所有事、今晚加班也要处理掉的那个档位。
受影响的是 8.2.35、8.3.36、8.4.27、8.5.12 以下的版本。
低于这几个号,全军覆没,全带病。
其中拿 Apache 加 mod_php 方式跑 PHP 的风险最高,HestiaCP 用户默认走 FPM,算是不幸中的万幸。
这次动静有多大呢。
维基百科主动把一堆服务下了线,日本那边从政府网站到航空公司,排队挂维护公告。
全球七成网站的地基,被一个内存漏洞晃了一下。
对了,这事还有个后续。
据说是一位老哥提前把漏洞消息捅到了网上,官方被迫把补丁提前放了出来。
提前公布漏洞,在安全圈是大忌,等于给攻击者递刀子。
这事闹得挺大,那位老哥后来也公开道歉了。
怎么说呢,好心办了坏事,立场问题我不评价。
但站在我们这些赶稿的人角度,还是想说声谢谢。
不然现在大家可能还在裸奔。
也有人说,套个 WAF 规则挡一挡不就行了。
怎么说呢,WAF 能挡一阵,但它挡的是已知的姿势。
对方换个打法,规则就得跟着追。
升级是治本,WAF 是止痛片。
疼得厉害的时候可以吃,但病还是要治的。
最魔幻的是,这漏洞据说是安全公司的人拿 AI 辅助审计源代码挖出来的。
AI 挖洞,人加班补洞,这世道。
我有时候也会瞎想,屏幕那头扫描我们的人,可能也就是个普通打工人。
说不定也是半夜被拉起来加班,对着自动化脚本,一片一片地扫过去。
但我也就瞎想。
想归想,补丁还是得打。
动手之前,先做一件比升级更重要的事
背景聊完了,下面全是干货。
当然,我也知道,看文章的各位,处境差得远。
有人用宝塔,有人裸装 nginx,还有人压根不运维服务器,只是自己的网站突然打不开了,搜到这来。
不管你是哪种,今晚的核心动作都一样,把 PHP 版本提到安全线以上,然后重启,然后校验。
这套流程我按 HestiaCP 的环境写,用别的面板的朋友,思路通用,换个路径而已。
HestiaCP 就是个免费开源的服务器管理面板。
浏览器里点几下就能kūkulu i kahi pūnaewele、开邮件、管数据库,适合不想天天对着黑窗口较劲的人。
它默认的多 PHP 走的是 Sury 源。
Sury 是 Debian 圈子里一位大神维护的 PHP ʻŌnaehana源,全世界的 VPS 几乎都在用,补丁跟进速度嗖嗖的。
这次 Sury 跟得很紧,所以你只要是 HestiaCP 默认装法,apt 一升级就能吃到修复。
但先别急着敲命令。
第一步,快照。
去云厂商控制台,找到快照按钮,点下去,等它跑完。
这一步花的时间,比你后面所有步骤加起来都长。
但也是今晚最值的一笔时间投资。
真的,听我说,这步偷懒省下的十分钟,可能就是未来你哭着加班的三个小时。
备份完了,SSH 上去,root 执行,四行。
apt update
apt upgrade php8.5* -y
systemctl restart php8.5-fpm
systemctl restart nginx敲完,收工。
如果你服务器上还跑着别的 PHP 分支,8.2、8.3、8.4 这些,同样有这个漏洞,一并升级,别留后患。
apt upgrade php8.2* php8.3* php8.4* -y
systemctl restart php8.2-fpm php8.3-fpm php8.4-fpm这里有个小建议。
命令最好一条一条敲,别图快直接复制一大段。
倒不是不信任你的复制粘贴技术。
是每敲一条,你都能亲眼看到系统回了你什么。
这种掌控感,是你跟你服务器之间信任的一部分。
这话听着有点玄,但你运维久了就懂了。
我以前也不信这套,总觉得自己是老手,闭着眼睛都不会错。
后来吃了几次亏才明白,越是老手,越容易在熟悉的地方翻车。

熟悉会让人变快,也会让人变糙。
一条一条敲,就是逼自己慢下来。
升级完不校验,等于白升
好,命令敲完了,你以为今天这就结束了。
ʻAʻole.
坦率的讲,我见过太多人在下一步翻车,包括我自己。
包是升级了,但 FPM 进程没重启,那个旧的、带漏洞的运行时,还赖在内存里喘着粗气。
攻击者扫的可不是你的版本号。
扫的是那个还在苟延残喘的老进程。
ʻo kahi laʻana.
版本号相当于门牌号,进程相当于屋里的人。
你把门牌换成了新的,屋里那个该走的没走,该防的照样防不住。
所以重启这一步,看着多余,其实才是补丁真正生效的临门一脚。
所以必须校验。
php8.5 -v输出里得清清楚楚看到 PHP 8.5.12,才算修好。
没看到,就回去查,别抱任何侥幸心理。
你想想看,扫描你的那个脚本,它可不困,也不累,全天候在线。
比你还敬业。
Hiki iā ʻoe ke manaʻoʻiʻo?
回面板再确认一眼,双保险
命令行搞定完,我们再回 Hestia 面板看一眼,图个双保险。
反正我觉得,双保险这事,怎么强调都不过分。
跑一下这个。
v-list-sys-php它会列出面板识别到的所有 PHP 版本。
对一下号,8.5.12 应该乖乖躺在里头。
有朋友可能会问,面板 Web 设置里,每个网站的 PHP 后端模板,要不要重新选一遍。
ʻAʻole pono.
我跟你说,包升级加上重启 FPM,模板自动就生效。
面板那只是个开关,不是玄学。
这点小事上,Hestia 还是挺省心的。
顺手多说一句面板里的门道。
Hestia 的 PHP 后端模板,拆开看就是一堆预配置好的 FPM 参数套餐。
你选哪个模板,决定的是用哪个 socket、跑哪个用户。
这些跟 PHP 二进制本身的版本是两回事。
所以包一升,二进制换新,模板那套参数原样套在新版本上,照样跑。
真正要留意的,是升级后进面板看一眼网站的状态灯。
全是绿的,才算完。
有一盏黄的,别拖,当场查。
三个常见的坑,我全替你踩过了
下面是大家喜闻乐见的踩坑环节。
我尽量写得诚实一点。
毕竟谁的钱都不是大风刮来的,服务器说挂就挂,谁也顶不住。
第一个坑,apt 提示源里找不到包。
大概率是 Sury 源没加对,或者密钥过期了。
重新导入一下 keyring 就好。
keyring 是啥呢,就是系统存放官方签名钥匙的地方。
apt 装包之前,会拿这把钥匙验一下包是不是官方发的,防止半路被人换了货。
钥匙过期了,系统就会疑神疑鬼,宁可错杀也不放过。
重新导入一遍,相当于给系统配一把新钥匙。
curl -fsSL https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /usr/share/keyrings/sury-keyring.gpg第二个坑,升级完网站直接 502。
先别慌,去看看 pool 配置和 socket 权限,九成的问题都趴在这俩地方。
Hestia 一般不会动这些,但你的魔改会。
这话是真的,我自己就是那个爱魔改的。
第三个坑,也是最扎心的一个。
PHP 8.1 及更早的版本,官方已经停止支持,这次没有补丁。
没有补丁是什么意思呢。
就是这个洞永远戳在那,你今天不处理,明年也不会有官方来救你。
只能下线,或者迁移。
我知道迁移很烦,是真的烦。
站点、扩展、配置,哪哪都是历史包袱。
其实吧,我自己的一个老站点,至今还赖在 8.1 上没舍得动。
每次想迁移,看看那一堆祖传扩展,就默默关掉了终端。
但怎么说呢,有些事烦归烦,还是得做。
服务器这东西,你糊弄它一时,它早晚糊弄你一回。
这话我送给你,也送给我自己。
今晚打完补丁,明天该迁移的迁移,该下线的下线。
别学我,老站点一拖再拖。
临走前,聊点比补丁更虚的
写了这么多,也不知道对大家有没有用,但我已经毫无保留了。
命令说完了,聊点虚的。
忙活完,你可能会觉得,安全嘛,就是打补丁、就是重启、就是命令行里那几行字。
我以前也这么觉得。
直到这次半夜被告警叫醒,翻着那一串扫描记录,我才又确认了一遍那个老道理。
安全从来不是一个动作。
它是一种习惯。
是你明明困得要死,还是选择爬起来跑一遍 php8.5 -v。
是你明明觉得麻烦,还是在升级前点下了那个快照。
是你跟服务器之间,日复一日攒下来的那点信任。
信任这东西,建起来慢,毁起来只要一个没重启的进程。
服务器不会说话,但它什么都记得。
你对它的每一次上心,它记得。
你对它的每一次侥幸,它也记得。
我们总以为安全是盾,是墙,是买了就能睡好的防火墙。
后来才发现,安全更像一段关系。
你跟服务器互相认得对方,知道彼此的脾气,也知道彼此的底线。
这种关系没法外包,也没法一劳永逸。
它就是你今晚敲下的每一条命令,和每一次心甘情愿的麻烦自己。
所以今晚,别裸奔。
去把补丁打了。
去把版本验了。
然后踏踏实实睡个觉。
这玩意,睡个好觉,比啥都重要。
真的。
No ka mea ua heluhelu ʻoe a hiki i kēia manawa, inā ʻike ʻoe he kōkua ia, e ʻoluʻolu e makemake a kaʻana like. Inā makemake ʻoe e loaʻa mua nā mea hou, hiki iā ʻoe ke hahai mai iaʻu! ⭐
Mahalo no ka heluhelu ʻana i kaʻu ʻatikala. A hui hou kākou.
Hope Chen Weiliang Blog ( https://www.chenweiliang.com/ ) 分享的《HestiaCP紧急修复PHP2Shell高危漏洞(CVSS 9.2):服务器安全排查与升级指南》,对您有帮助。
E ʻoluʻolu e kaʻana like i ka loulou o kēia ʻatikala: https://www.chenweiliang.com/cwl-34629.html
