运维灾难:Linux - 0 Day 漏洞让我彻夜难眠
双 0 Day 凌空来袭,全网运维集体头皮发麻
声明:本文所涉及的漏洞原理、复现步骤、利用代码,仅可用于内部授权安全测试、合规漏洞研究与加固演练。严禁私自用于未授权服务器入侵、非法越权操作等违规违法行为,违者需自行承担全部法律责任与相关后果!
一、平静被撕开一道口子
4 月 30 日下午 17 点,腾讯云服务器的售后群突然发送紧急通知:
“Copy Fail 潜伏的 Linux 本地提权漏洞,CVE-2026-31431,POC 已公开。”
我下意识看了一眼自己的服务器内核版本:6.12.57+deb13-amd64,刚好在受影响范围内。
这个漏洞不需要竞争条件,成功率接近 100%。普通用户只需执行一段 732 字节的 Python 脚本,就能利用 algif_aead 模块将 /usr/bin/su 的内存改写。之后任何人在终端敲一个 su,回车,直接变 root。
更让我后背发凉的是:所有主流发行版均无补丁。
上游在 4 月 1 日就修了,但因为协调披露流程,补丁还卡在发行版的 backport 环节。4 月 29 日漏洞被提前公开,各大厂商直接被打了个措手不及。
我当时的心情,像看到自家门锁被人挂到网上配了万能钥匙,而换锁的师傅还要好几天才能到。
二、验证
我立即在内网服务器部署了镜像,就是想亲自看看这个漏洞。
- 测试机:Debian 13,内核 6.12.57+deb13-amd64(未修复状态)
- 普通用户:testuser(无 sudo 权限)
- 网络:已断开外网(内网隔离)
Copy Fail 的利用代码已经在 GitHub 上公开。我以 testuser 身份登录测试机:
$ git clone https://github.com/theori-io/copy-fail-CVE-2026-31431.git
$ cd copy-fail-CVE-2026-31431随后验证文件完整性:
$ sha256sum copy_fail_exp.py
a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9 copy_fail_exp.py接下来,直接执行脚本:
$ python3 copy_fail_exp.py
#是的,脚本运行仅 2~3 秒,无报错、无卡顿,终端提示符瞬间从普通用户 $ 变为 root 权限 # 。
你不信?请执行 whoami 指令试试:
# whoami
root我后背一凉。一个普通用户,一行 Python,三秒钟,直接拿到整个服务器的 root。
三、封堵
验证完成,接下来是真正的工作,封堵。
官方补丁还没出来,我不能坐等。临时缓解措施只有一条:让内核永远无法加载 algif_aead 模块。
1. 立即生效的封堵命令
切回 root 用户:
echo "install algif_aead /bin/false" > /etc/modprobe.d/block-algif.conf
rmmod algif_aead 2>/dev/null
update-initramfs -u解释一下这三条命令:
install algif_aead /bin/false:告诉内核,任何试图加载algif_aead模块的操作,都执行/bin/false(加载失败)。rmmod algif_aead:如果模块已经加载,立即卸载(2>/dev/null忽略错误)。update-initramfs -u:将配置写入初始化内存盘,确保重启后依然生效。
2. 验证封堵是否有效
重启测试机(必须重启,因为页缓存中的脏数据还在):
reboot重新以 testuser 登录,再次尝试利用:
$ python3 copy_fail_exp.py
Error: Module algif_aead not available
$ su
Password: # 仍然需要密码,无法提权封堵成功。
四、暴雨前的宁静
Copy Fail 封堵后的那几天,我每天都会检查一遍安全公告。官方补丁迟迟没出来,各大发行版的回答永远是“正在准备中”。
我一度以为,危机已经解除,只需要静候补丁就万事大吉了。服务器静悄悄地跑着,没有异常登录,没有 CPU 飙升,没有报警短信。
直到 5 月 7 日。
傍晚,群里又炸开了锅,又是一个 Linux 内核本地提权漏洞,名字叫 Dirty Frag。我点开链接,越看越心惊。
1. 它比 Copy Fail 更野
Dirty Frag 属于同一个漏洞家族(零拷贝路径 + splice() + 页缓存),但这次不是只改一个模块,而是 两个独立模块各有一个变体:
| 变体 | 模块 | 权限要求 | 攻击效果 |
|---|---|---|---|
| ESP | esp4 / esp6 | 需要 user_namespace | 篡改任意只读文件的内存页(如 /usr/bin/su) |
| RxRPC | rxrpc | 完全不需要任何权限 | 直接清空 /etc/passwd 中 root 的密码字段 |
两个变体互相覆盖对方的限制:如果你的内核不支持 user_namespace,ESP 变体失效,但 RxRPC 变体依然有效;反之如果 RxRPC 模块被禁用,ESP 变体也能单独完成提权。
官方公告里写着:单一攻击程序可在几乎所有主流 Linux 发行版上通用。
而且,当时所有发行版 均无补丁。
为什么?上游在 5 月 7 日刚合并了 ESP 模块的修复,RxRPC 的修复还没影子。而正常的协调披露流程需要给发行版 14 天左右的 backport 时间,结果漏洞被第三方提前公开,利用代码直接上传到了 GitHub。
我登录生产服务器,心跳加速。
2. 我必须亲眼看到
跟上次一样,我先在内网测试机上验证。测试环境不变。
$ git clone https://github.com/v4bel/dirtyfrag.git
$ cd dirtyfrag
$ ls
exp.c README.md assets编译:
$ gcc -o exp exp.c -lutil
$ ./exp
#又是三秒,又是一个 #。我试了一下:
# whoami
root更可怕的是 RxRPC 变体,它不需要创建用户命名空间,在默认封锁严格的系统上也能跑。我单独测试了 RxRPC 的利用:
$ ./exp_rxrpc # 另一个预编译的变体
[+] Root password cleared, try 'su -'
$ su -
# 我检查 /etc/passwd,发现 root: 变成了 root::——密码字段被清空了。
这时我才真正感到后怕。Copy Fail 好歹需要接触 algif_aead 模块,而 Dirty Frag 的 RxRPC 变体,完全不需要任何权限,任何一个能登录服务器的普通用户,一行命令,就能把 root 密码抹掉。
3. 双重封堵
我立刻登录生产服务器,先检查三个模块的状态:
lsmod | grep -E "esp4|esp6|rxrpc"
# 没有输出然后用官方推荐的封堵命令,新建一个配置文件:
printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf
rmmod esp4 esp6 rxrpc 2>/dev/null
update-initramfs -u这时我的 /etc/modprobe.d/ 目录下有两个封堵文件:
block-algif.conf:禁用algif_aead(防Copy Fail)dirtyfrag.conf:禁用esp4、esp6、rxrpc(防Dirty Frag)
互不冲突,协同防御。
五、内核升级
两个漏洞都临时封堵了,但我心里清楚:禁用模块只是缓兵之计。真正的安全感,只能来自上游补丁。
5 月 8 日,Debian 仓库终于推送了 linux-image-6.12.85。我立刻查看 changelog:
apt changelog linux-image-6.12.85+deb13-amd64 | grep -i "cve-2026-31431"
crypto: algif_aead - Revert to operating out-of-place (CVE-2026-31431)Copy Fail 已经修复:官方通过回退(revert)的方式,彻底消除了 algif_aead 模块中的“原地操作”缺陷。这意味着即使模块被加载,也不会再造成提权。
但 Dirty Frag 的 RxRPC 部分,changelog 里没有任何相关字样。我再次确认:
apt changelog linux-image-6.12.85+deb13-amd64 | grep -i "rxrpc"
# 虽然有几十条 rxrpc 相关的修复,但没有一条是针对页缓存写入的补丁也就是说,哪怕升级到最新内核,RxRPC 变体依然危险。我必须保留对 rxrpc 模块的禁用。
1. 执行升级
决定升级后,我执行了标准流程:
apt update
apt upgrade -y升级过程中遇到了 OpenSSH 配置文件冲突。因为我之前修改过 /etc/ssh/sshd_config(改端口、禁止密码登录等)。我选择了 保留本地版本,继续升级。
升级完成后,确认新内核已安装:
dpkg -l | grep linux-image | grep 6.12.85
ii linux-image-6.12.85+deb13-amd64 6.12.85-1 amd64 Linux 6.12 for 64-bit PCs
ii linux-image-amd64 6.12.85-1 amd64 Linux for 64-bit PCs (meta-package)2. 重启 + 验证
重启是必须的,否则新内核不会生效。
reboot重新登录后:
uname -r
6.12.85+deb13-amd64检查漏洞相关的所有模块:
lsmod | grep -E "esp4|esp6|rxrpc|algif_aead"
# 没有任何输出algif_aead没有加载——即使加载也不再有漏洞,但我保留着/etc/modprobe.d/block-algif.conf,暂时没动。esp4/esp6/rxrpc依然被dirtyfrag.conf中的install /bin/false拦截。
我又用测试机验证了一遍升级后的效果:
- Copy Fail:
algif_aead可以被正常加载,但无法提权(内核已修复)。 - Dirty Frag (ESP):由于新内核包含 ESP 补丁,即使不封堵也安全。
- Dirty Frag (RxRPC):仍然危险,必须继续禁用
rxrpc。
六、写在最后
从 4 月 30 日到 5 月 10 日,整整十一天。两个 0day,四次封堵,一次内核升级,无数次心跳加速。
我学到了三件事:
-
0day 的空窗期,没有补丁 ≠ 没有防御。 因此模块禁用是最古老、也最可靠的临时手段。只要业务不受影响,直接把危险模块
install /bin/false,比等补丁更管用。 -
任何配置修改,只有重启之后还能自动拉起所有服务,才算真正完成。我这次因为 PM2 未正确配置开机自启,导致博客服务中断——这是不该犯的低级错误。
-
运维笔记必须可复现。 只记录“我做了什么”是不够的,还要写下“别人照着做也能成功”。POC 的哈希、精确的命令、封堵前后的对比,缺一不可。
天亮之后,补丁会来,服务器会继续跑。但这份笔记会留下来,成为下一次风暴来临时的灯塔。
愿每一次 0day,你的防线都跑在攻击者前面。
本文所有命令已在 Debian 13 / 内核 6.12.57 上验证。
声明:本文所涉及的漏洞原理、复现步骤、利用代码,仅可用于内部授权安全测试、合规漏洞研究与加固演练。严禁私自用于未授权服务器入侵、非法越权操作等违规违法行为,违者需自行承担全部法律责任与相关后果!