SpenserCai/copy_fail

GitHub: SpenserCai/copy_fail

针对 CVE-2026-31431 Linux 内核 AF_ALG 页缓存本地提权漏洞,提供 Rust 编写的确定性漏洞利用 PoC 及无需重启即可部署的 eBPF 运行时防御工具(LSM/kprobe 双模式)。

Stars: 2 | Forks: 0

# 复制失败 — CVE-2026-31431 CVE-2026-31431 (Copy Fail) 是 Linux 内核 `algif_aead` 模块(AF_ALG 子系统)中的一个本地提权漏洞。该漏洞源于 2017 年 8 月引入的一个逻辑缺陷,允许任何无特权的本地用户通过 `AF_ALG` + `splice()` 向任何可读文件的页缓存中写入 4 个可控字节,然后执行一个被篡改的 setuid 二进制文件以获取 root 权限。该漏洞利用是确定性的——没有竞态条件,不需要内核偏移,也不会导致系统崩溃。它影响了所有搭载 4.14 到 7.0-rc 内核的主要 Linux 发行版。 CVSS: 7.8 | 修复于: kernel 7.0, 6.19.12, 6.18.22 | 主线修复: commit `a664bf3d603d` 来源: [copy.fail](https://copy.fail), [The Hacker News](https://thehackernews.com/2026/04/new-linux-copy-fail-vulnerability.html), [CloudLinux advisory](https://blog.cloudlinux.com/cve-2026-31431-copy-fail-kernel-update) ## 项目结构 ``` crates/ ├── exp/ # Exploit PoC (Rust reimplementation) ├── copy_fail_guard/ # Userspace eBPF loader — LSM mode ├── copy_fail_guard-ebpf/ # eBPF LSM program (not in workspace) ├── copy_fail_guard_kprobe/ # Userspace eBPF loader — kprobe mode └── copy_fail_guard_kprobe-ebpf/ # eBPF kprobe program (not in workspace) scripts/ └── build_guard.sh # One-click build → outputs to dist/ ``` ## 漏洞概述 根本原因是三个独立的内核特性进行不安全交互所形成的链条: 1. **`AF_ALG` socket** — 将内核加密 API 暴露给无特权的用户空间 2. **`splice()`** — 零拷贝传输将文件数据作为页缓存引用(而不是副本)转移到加密分散列表中 3. **`authencesn` AEAD 模板** — 使用调用者的输出缓冲区作为临时空间,在 `dst[assoclen + cryptlen]` 处写入 4 个字节 2017 年,`algif_aead.c` 中的就地优化(`72548b093ee3`)使得 `req->src == req->dst`,将页缓存页面链接到可写的目标分散列表中。当 `authencesn` 写入其临时字节时,它会越过输出缓冲区进入链接的页缓存页面。攻击者可以控制: - **哪个文件**:当前用户可读的任何文件 - **哪个偏移量**:由 splice 偏移量、splice 长度和 assoclen 决定 - **哪 4 个字节**:来自 AAD 字节的 4–7(seqno_lo),在 sendmsg() 中设置 被破坏的页面永远不会被标记为脏页——磁盘上的文件保持不变,但 `execve()` 会从页缓存中读取数据。破坏一个 setuid 二进制文件即可获得 root 权限。 ## crates/exp — 漏洞利用 PoC 这是对公开的 732 字节 Python PoC 的 Rust 重实现。其目标是 `/usr/bin/su`,将其页缓存页拼接到一个 AF_ALG AEAD socket 中,并使用压缩的 shell 载荷覆盖它们。 ### 构建 需要 Rust 1.85+(edition 2024)。 ``` cargo build --release -p copy_fail ``` 该二进制文件仅限 Linux 运行。在其他平台上,它将以 `Unsupported` 错误退出。 ### 运行 1. 启动运行易受攻击内核的虚拟机(任何内核版本 < 7.0 / < 6.19.12 / < 6.18.22 的主流发行版)。 2. 将构建好的二进制文件复制到虚拟机中,并以非 root 用户身份运行它: ./target/release/copy_fail 3. **易受攻击**:将出现一个 root shell (`#`)。运行 `whoami` 确认显示为 `root`。 4. **非易受攻击**(已修补的内核):AF_ALG 操作将失败,或者 `su` 二进制文件行为正常。您将看到一个错误或常规的 `su` 密码提示。 ## 防御工具 — copy_fail_guard 一个无需升级内核或重启即可拦截 CVE-2026-31431 的运行时内核防御工具。它利用 eBPF 拦截 `AF_ALG` socket 的创建,从而切断漏洞利用的第一步。 提供了两种模式。一键加载器会自动选择可用的最佳模式: | | LSM 模式 | kprobe 模式 | |---|---|---| | **拦截方式** | 返回 `-EPERM` (拒绝创建 socket) | `SIGKILL` (终止进程) | | **内核要求** | ≥ 5.7 且带有 `lsm=bpf` 引导参数 | ≥ 5.3,无需特殊参数 | | **是否需要重启才能启用** | 可能需要 (如果尚未设置 `lsm=bpf`) | **否** | | **Hook 点** | `socket_create` LSM hook | `__sys_socket` kprobe | ### 工作原理 ``` ┌──────────────────────────────────────────────────┐ │ run_guard.sh │ │ • Detects BPF LSM support │ │ • LSM available → copy_fail_guard (EPERM) │ │ • LSM unavailable → copy_fail_guard_kprobe (KILL)│ └──────────────┬───────────────────────────────────┘ │ ┌──────────────▼───────────────────────────────────┐ │ eBPF program │ │ if socket family == 38 (AF_ALG) │ │ → block (EPERM or SIGKILL) │ │ else │ │ → allow │ └──────────────────────────────────────────────────┘ ``` ### 对系统的影响 阻止 `AF_ALG` 对典型系统具有**几乎为零的影响**: - **不受影响**:dm-crypt/LUKS、kTLS、IPsec/XFRM、OpenSSL/GnuTLS/NSS(默认构建)、SSH、内核密钥环加密——这些都直接使用内核内加密 API,而不是通过 `AF_ALG` - **潜在受影响**:显式配置为使用 `AF_ALG` 的应用程序(例如,启用了 `afalg` 引擎的 OpenSSL,一些嵌入式加密卸载路径) - **性能**:对于不调用 `socket(AF_ALG, ...)` 的程序没有任何开销 ### 构建 **一键构建**(推荐): ``` ./scripts/build_guard.sh ``` 这将自动安装缺失的工具链(nightly, bpf-linker),编译所有 eBPF 程序和用户空间加载器,并将所有内容输出到 `dist/`: ``` dist/ ├── copy_fail_guard.bpf.o # eBPF LSM program ├── copy_fail_guard_kprobe.bpf.o # eBPF kprobe program ├── copy_fail_guard # Userspace loader (LSM) ├── copy_fail_guard_kprobe # Userspace loader (kprobe) └── run_guard.sh # Auto-select: sudo ./run_guard.sh ``` 将 `dist/` 目录复制到任何目标机器并运行 `sudo ./run_guard.sh` 即可激活保护。 **手动构建**(分步执行): 步骤 1:编译 eBPF 程序(必须在 Linux 上进行): ``` # LSM 变体 cd crates/copy_fail_guard-ebpf cargo +nightly build --target bpfel-unknown-none -Z build-std=core --release # kprobe 变体 cd crates/copy_fail_guard_kprobe-ebpf cargo +nightly build --target bpfel-unknown-none -Z build-std=core --release ``` **步骤 2:构建用户空间加载器**: ``` cargo build --release -p copy_fail_guard -p copy_fail_guard_kprobe ``` ### 运行 **推荐方式** — 自动选择最佳模式: ``` sudo ./dist/run_guard.sh ``` **手动方式** — 运行特定模式: ``` # LSM 模式 (需要 lsm=bpf) sudo GUARD_BPF_OBJ=path/to/copy_fail_guard.bpf.o RUST_LOG=info ./copy_fail_guard # kprobe 模式 (随处可用) sudo GUARD_BPF_OBJ=path/to/copy_fail_guard_kprobe.bpf.o RUST_LOG=info ./copy_fail_guard_kprobe ``` 按下 `Ctrl-C` 可分离 eBPF 程序并恢复正常行为。 ### 验证防御效果 在一个终端中运行 guard 的情况下: ``` # 在另一个终端中,尝试运行 exploit: ./target/release/copy_fail # LSM 模式:"error: Operation not permitted" # kprobe mode: "已杀死" / "Killed" # 或者直接使用 Python 测试: python3 -c "import socket; socket.socket(38, 5, 0)" # LSM 模式:PermissionError: [Errno 1] Operation not permitted # kprobe 模式:Killed ``` ### 当前局限性 - **尚不支持白名单** — 当前版本无条件阻止所有用户空间的 `AF_ALG` socket 创建。目前没有机制通过 PID、cgroup 或命令名来豁免特定进程。这计划在未来版本中实现(通过 eBPF HashMap 映射)。对于绝大多数系统来说这没有问题,因为几乎没有任何程序使用 `AF_ALG`。 - eBPF crate 必须在 Linux 下使用 `bpf-linker` 单独编译(它们的目标是 `bpfel-unknown-none`,不能作为普通的 workspace 成员)。 - 保护仅在加载器进程运行期间生效。如需持久化保护,请将其作为 systemd 服务运行。 ### 启用 BPF LSM(可选,用于 LSM 模式) 大多数发行版默认不启用 BPF LSM。如果您想使用更干净的 LSM 模式(返回 EPERM 而不是 SIGKILL): ``` # 检查当前 LSM: cat /sys/kernel/security/lsm # 如果缺少 "bpf",请添加它: sudo sed -i 's/^GRUB_CMDLINE_LINUX="\(.*\)"/GRUB_CMDLINE_LINUX="\1 lsm=lockdown,capability,yama,apparmor,bpf"/' /etc/default/grub sudo update-grub && sudo reboot ``` kprobe 模式无需此步骤即可工作。 ## 验证内核修复 在将内核修补到 ≥ 7.0 / ≥ 6.19.12 / ≥ 6.18.22 之后: ``` # 确认内核版本 uname -r # 重新运行 exploit — 它应该不再生成 root shell ./target/release/copy_fail ``` 或者,确认易受攻击的模块已被中和: ``` modinfo algif_aead | grep filename # 如果是内置的,请将 initcall 加入黑名单 (需要重启) sudo grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init" sudo reboot ```
标签:0day挖掘, AF_ALG, algif_aead, Copy Fail, CVE-2026-31431, Docker镜像, EXP, kprobe, Linux内核漏洞, LPE, LSM, Rust, setuid, splice, Web报告查看器, 内核安全, 内核攻防, 内核防御, 可视化界面, 子域名枚举, 安全渗透, 底层安全, 本地提权, 漏洞PoC, 系统安全, 网络安全, 网络流量审计, 虚拟化安全, 通知系统, 隐私保护, 零拷贝, 页面缓存