rfxn/copyfail
GitHub: rfxn/copyfail
针对 CVE-2026-31431 Linux 内核 AF_ALG 本地提权漏洞的纵深防御工具包,提供用户态 LD_PRELOAD 阻断、内核模块黑名单和安全态势审计,无需重启即可部署。
Stars: 5 | Forks: 0
# copyfail - CVE-2026-31431
**通过 AF_ALG `authencesn` 页缓存原语实现本地提权。**
内核在对 AEAD 解密时发生边界计算错误,将攻击者可控的字节写入任意 SUID 二进制文件或特权配置文件的页缓存中。
磁盘上的文件没有任何更改;这种破坏仅存在于 RAM 中直到被驱逐。
不会留下任何磁盘上的取证痕迹。
用户态纵深防御:一个阻断 `AF_ALG` socket 创建的 `LD_PRELOAD` shim 以及一个只读的主机安全态势审计工具。
已签名的适用于 EL8 / EL9 / EL10 的 RPM 包。
[](#what-this-protects-against)
[](#what-this-protects-against)
[](LICENSE)
[](https://rfxn.github.io/copyfail/)
[](https://github.com/rfxn/copyfail/releases/latest)
[安装](#install) · [审计](#audit-the-host) · [纵深防御](#defense-in-depth-where-this-rung-carries-weight-on-its-own) · [子包](#subpackages) · [验证签名](#verifying-signatures)
## 安装
```
sudo curl -sSL https://rfxn.github.io/copyfail/copyfail.repo \
-o /etc/yum.repos.d/copyfail.repo
sudo dnf install -y afalg-defense
```
一个 repo 文件即可适用于 EL8/EL9/EL10(dnf 会根据主机替换 `$releasever`/`$basearch`)。RPM 包经过 GPG 签名;dnf 在首次使用时会导入公钥——请在出现提示时交叉比对指纹:
```
6001 1CDC EA2F F52D 975A FDEE 6D30 F32C D5E8 0F80
```
仅安装审计工具(无 `LD_PRELOAD`,适用于关键在线基础设施):
```
sudo dnf install -y afalg-defense-auditor
```
## 激活 shim
shim 已安装但**不会自动启用**。在 `%post` 阶段直接修改 `/etc/ld.so.preload` 会在任何升级失败时导致主机变砖——因此激活过程需要运维人员显式操作:
```
sudo /usr/sbin/copyfail-shim-enable # smoke-tests, then writes /etc/ld.so.preload
sudo /usr/sbin/copyfail-shim-disable # reverses it
```
启用辅助程序会先执行 `LD_PRELOAD=$shim /bin/true`;如果无法加载该 .so 文件,辅助程序将拒绝更新配置文件,以免将您锁定在外。
## 同时黑名单 AF_ALG 模块(在可加载的情况下)
本软件包还附带了一个门槛同样极低的缓解措施:一个 `modprobe` drop-in 配置,可在内核层面切断 `algif_aead`、`authenc` 和 `authencesn`。当您的内核将 AF_ALG 作为可加载模块暴露时(大多数主线内核都是如此),这**与 shim 叠加使用**,且应受到同等重视。shim 在 libc 层阻断所有用户态调用者;而黑名单则彻底移除了内核攻击面。机制不同,但对运维人员来说都只需执行一行命令。
```
# 决定黑名单在此内核上是否生效。
ls /sys/module/algif_aead 2>/dev/null && echo "modular - blacklist effective" \
|| echo "builtin or absent - shim is your primary defense"
grep -E 'ALG_USERMODE|CRYPTO_USER_API' /boot/config-$(uname -r) 2>/dev/null
# =m -> modular(以黑名单为主) =y -> builtin(以 shim 为主)
# 如果是 modular,请在 /etc/modprobe.d/ 中放入黑名单,并卸载
# 所有已驻留的模块。CVE-2026-31431 链是位于底部的 trio;
# algif_* 系列是为了常规的 AF_ALG 卫生而添加的。
sudo tee /etc/modprobe.d/99-no-afalg.conf >/dev/null <<'EOF'
install af_alg /bin/false
install algif_aead /bin/false
install algif_skcipher /bin/false
install algif_hash /bin/false
install algif_rng /bin/false
install authenc /bin/false
install authencesn /bin/false
EOF
sudo rmmod algif_aead authenc authencesn 2>/dev/null || true
```
(该软件包也将此文件附带在 `/usr/share/doc/afalg-defense/examples/no-afalg-modprobe.conf` 中——内容相同,如果您希望保留审计轨迹,可以将其复制到相应位置。)只要内核允许,请**同时**部署 shim 和黑名单——只需两条 `sudo` 命令即可获得双重保障。
## 验证
```
python3 -c 'import socket; socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)'
# 预期:PermissionError [Errno 1] Operation not permitted
```
被阻断的尝试会记录到 `auth.priv`:
```
no-afalg[12345]: blocked AF_ALG (domain=38) via socket uid=0 euid=0 pid=12345
```
## 审计主机
```
sudo copyfail-local-check # human-readable, only flags non-OK
sudo copyfail-local-check --json # SIEM ingestion (posture.verdict)
sudo copyfail-local-check --emit-remediation # bash script of suggested fixes
```
设计上为只读:仅通过 `mkdtemp()` 哨兵文件进行写入,从不修改 `/usr/bin` 或 `/etc`,以非特权身份运行(部分检查在无 root 权限时会优雅降级)。五大类别:`ENV`、`KERNEL`、`MITIGATION`、`HARDENING`、`DETECTION`。
退出码:`0` 安全 · `2` **存在漏洞 (VULN)**(无用户态缓解措施) · `3` 存在漏洞但已缓解 · `4` 仅有安全加固建议。
## 移除
```
sudo /usr/sbin/copyfail-shim-disable
sudo dnf remove afalg-defense afalg-defense-shim afalg-defense-auditor
```
`%preun` 在完全卸载时也会作为安全网清除 `/etc/ld.so.preload`,但先进行禁用可使操作过程更加透明。
## 防护范围
`AF_ALG` 的 `authencesn(hmac(sha256),cbc(aes))` AEAD 路径在解密时错误计算了输出长度,向用户态返回了比实际经过身份验证的字节数更多的数据。当该解密操作的目标是一个从 SUID 二进制文件或特权配置文件的页缓存拼接而来的管道时,内核会将攻击者控制的字节写入干净的页缓存页中——这对后续的所有读取者(包括通过 `execve()` 执行 `/usr/bin/su`)都是可见的。**磁盘文件没有任何更改**;这种破坏仅存在于 RAM 中,直到页面被驱逐。
这构成了一个本地权限提升原语,不需要攻击者加载内核模块(相关的加密模块在大多数发行版上会被 `socket(AF_ALG, ...)` 自动加载),并且**不会在磁盘上留下任何取证痕迹**。
## 纵深防御:此防御层的独立价值所在
针对 AF_ALG 类漏洞共有五层防御,且每一层都有其失效场景。本软件包的意义在于,击败其上层防御的条件**与击败 shim 的条件并不相同**——这正是使 shim 成为可行的主要防御手段,而不仅仅是备份的原因。
| 级别 | 失效场景 | shim 在此处的作用 |
|---|---|---|
| 1. 内核补丁 (厂商) | EL7 已停止维护 (EOL);EL8/EL9/EL10 补丁发布通常落后漏洞披露数天至数周;在漏洞被高频利用的时间窗口内,生产环境可能无法立即重启 | **无需重启即可填补时间窗口。** 热安装,无需触碰内核 |
| 2. 针对 `algif_aead` / `authenc` / `authencesn` 的 `modprobe` 黑名单 | 仅当这些模块作为**可加载模块**(而非内建)且在启动早期尚未驻留时有效。**在模块化内核上(大多数标准主线内核),这是与 shim 叠加使用的、门槛同样极低的主要防御手段**。当 `algif_aead` 是内建的(RHEL 默认)时,此措施无效 | **在内建加密算法的内核上接管防御**——每个用户态调用者无论内核如何暴露 AF_ALG,都必须经过 libc 的 `socket(2)` |
| 3. systemd `RestrictAddressFamilies=~AF_ALG` | 仅能覆盖应用该限制后由 systemd 启动的服务。无法涵盖 **cron 任务、sshd 登录 shell、带有独立 pid 1 的容器负载**,以及任何在应用限制之前启动的进程 | **全局生效。** `/etc/ld.so.preload` 适用于所有动态链接的进程,无论由哪个 init 系统启动 |
| 4. **`LD_PRELOAD` shim (本软件包)** | 静态编译的二进制文件;直接发起 `syscall` 指令的进程;SUID 二进制文件(内核会在安全执行时剥离 `LD_PRELOAD`) | (见右列的覆盖范围) |
| 5. seccomp 过滤器 (按单元 / 容器运行时) | 按服务生效。运维操作成本高:每个单元/运行时都需要显式配置策略 | **一个 .so 文件 + 一行 ld.so.preload 配置**即可覆盖整个主机 |
shim 自身失效的场景——静态二进制文件、直接使用 `syscall` 指令、SUID 剥离——属于**攻击者工程领域**。而其他层级失效则发生在**常规运维现实中**:厂商尚未发布补丁、内核内建了加密模块、威胁面包含 cron 任务等。这种不对称性正是优先部署此防御层的理由。
### 适用场景:当此方案作为主要防御手段时
- 厂商内核补丁尚未发布(零日漏洞窗口)。
- 补丁已发布,但您*现在*无法立即重启主机。
- 内核内建了 `algif_aead`(导致 `modprobe` 黑名单无效)。
- 您的威胁面包含 systemd 之外的任何事物—— cron、登录 shell、容器负载,以及任何继承自应用限制前单元的进程。
- 您没有足够的运维精力为每个守护进程编写针对特定服务的 seccomp 策略。
审计工具会针对运行中的主机对这五个层级进行评估,并告知您哪些已启用、哪些已过期、哪些可被绕过——这样您就可以在后续可用时补充额外的防御措施,而不会忽略当前真正起支撑作用的机制。
## shim 刻意不做之事
它不会封装 `syscall(2)`。无条件读取六个 `long` 类型的可变参数属于未定义行为,而且它能拦截的绕过方式(`syscall(SYS_socket, AF_ALG, ...)` 和内联汇编的 `syscall` 指令)从根本上无法从用户态阻断。请配合 seccomp 或内核补丁来应对该攻击面。
## 子包
| 软件包 | 架构 | 内容 |
|---|---|---|
| `afalg-defense` | x86_64 | 元软件包 —— 拉取 shim + 审计工具 |
| `afalg-defense-shim` | x86_64 | `/usr/lib64/no-afalg.so` + `copyfail-shim-{enable,disable}` |
| `afalg-defense-auditor` | noarch | `/usr/sbin/copyfail-local-check` (Python,仅依赖标准库,只读) |
针对不同 EL 版本的二进制 RPM 包是分别根据各自发行版的 glibc 独立编译的(EL8:2.28 拆分版 `libdl`;EL9/EL10:2.34+ 合并版 `libdl`)。**请勿跨 EL 版本混装。** 直接下载链接 + sha256 校验和:
[rfxn.github.io/copyfail](https://rfxn.github.io/copyfail/#direct-downloads)。
## 验证签名
1.0.1 及更高版本由 **Copyfail 项目签名密钥** 签名。
`.repo` 文件强制启用了 `gpgcheck=1`(针对每个 RPM)和 `repo_gpgcheck=1`(对元数据使用 detached 签名 `repomd.xml.asc`)——因此原生的 `dnf install` 即可自动完成端到端验证。
```
fingerprint: 6001 1CDC EA2F F52D 975A FDEE 6D30 F32C D5E8 0F80
uid: Copyfail Project Signing Key 标签:0day挖掘, AEAD, AF_ALG, authencesn, CentOS, Copy Fail, CVE-2026-31431, EL10, EL8, EL9, LD_PRELOAD, RHEL, Root权限, RPM, SUID, Web报告查看器, 主机安全态势, 代理, 内存破坏, 内存页缓存污染, 内核安全, 内核漏洞, 子域名枚举, 安全防护, 无文件攻击, 本地提权, 漏洞缓解, 系统安全, 纵深防御, 网络安全, 逆向工具, 隐私保护