algif_aead 本地权限提升CISA KEV | CVSS 7.8 高危 | 影响 Linux 内核 4.14 – 2026 年初(约 9 年)
CVE-2026-31431,绰号 “Copy Fail”,是 Linux 内核加密子系统中的一个高危本地权限提升(LPE)漏洞。低权限本地用户可在任何未打补丁的系统上数秒内提升至 root 权限。
| 属性 | 值 |
|---|---|
| CVE | CVE-2026-31431 |
| 绰号 | Copy Fail |
| CVSS v3.1 | 7.8 高危 |
| 攻击向量 | 本地 |
| 所需权限 | 低 |
| 用户交互 | 无 |
| 组件 | crypto/algif_aead.c — authencesn 模板 |
| 引入时间 | 2017 年(提交 72548b093ee3) |
| 披露时间 | 2026 年 |
| 潜伏年限 | 约 9 年 |
| CISA KEV | 是 |
| 公开 PoC | 是(732 字节独立 Python 脚本) |
detection/check_vulnerable.sh。CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
| Metric | Value | Rationale |
|--------|-------|-----------|
| 攻击向量 | **本地** | 需要 shell 访问权限(SSH、容器 exec、物理访问) |
| 攻击复杂度 | **低** | 可靠且完全自动化——无需竞态条件 |
| 所需权限 | **低** | 任意非特权用户账户 |
| 用户交互 | **无** | 无需受害者交互 |
| 机密性 | **高** | 完全系统沦陷 |
| 完整性 | **高** | 完全系统沦陷 |
| 可用性 | **高** | 完全系统沦陷 |
### 威胁态势
| 因素 | 评估 |
|--------|-----------|
| PoC 可用性 | 公开、已武器化、732 字节独立 Python |
| 漏洞利用可靠性 | 高——无需修改即可在测试过的发行版上运行 |
| 检测难度 | 高——无磁盘写入、无脏页 |
| 攻击者技能要求 | 低——使用公开 PoC 的脚本小子 |
| CISA KEV | 已于 2026 年添加——正在积极监控 |
| Microsoft Defender | 标记为正在积极调查中 |
### 受影响环境
| 环境 | 风险 |
|-------------|------|
| 裸机 Linux 服务器 | 严重 |
| Linux 虚拟机(云或本地) | 严重 |
| Kubernetes 节点 | 严重(同时可实现容器逃逸) |
| Docker 主机 | 严重 |
| 共享托管 / 多租户 | 严重 |
| WSL2 / Windows 上的 Linux | 按内核版本评估 |
---
## 3. 技术深度剖析
### 3.1 背景:AF_ALG 与 AEAD
Linux 内核通过 **AF_ALG 套接字**(`AF_ALG = 38`)向用户空间暴露加密操作。该接口(`algif_aead`)允许非特权应用程序调用内核加密硬件加速器,而无需内核态代码。
**AEAD**(带关联数据的认证加密)算法(如 AES-GCM 和 ChaCha20-Poly1305)广泛用于 TLS、磁盘加密和 VPN 协议。易受攻击的模板是 `authencesn`——一种使用 `hmac(sha256)` + `cbc(aes)` 并支持扩展序列号(ESN)的 AEAD 组合,常用于 IPsec。
### 3.2 根本原因
2017 年,提交 `72548b093ee3` 将**就地 AEAD 操作**引入 `algif_aead` 作为性能优化——允许加密引擎读写同一缓冲区。这存在缺陷:```
The bug chain:
1. Caller binds AF_ALG socket to:
authencesn(hmac(sha256),cbc(aes))
2. Caller sends a decryption request via sendmsg() with specific flags
3. Caller uses splice() to feed PAGE CACHE PAGES from an open file
descriptor directly into the socket's scatterlist
4. The authencesn template, during ESN header processing, uses the
OUTPUT BUFFER as scratch space — writing 4 bytes past the
expected output boundary
5. Because the scatterlist contains page cache pages (not private
copies), this scratch write lands DIRECTLY IN THE PAGE CACHE
6. Page cache is shared kernel-wide — all processes reading the
same file now see the modified bytes
Key insight: splice() is zero-copy — it hands page cache references
to the socket. The in-place "optimization" then writes INTO those
pages. No dirty bit is set because the write goes through the crypto
engine, not the normal write path.
该漏洞允许向攻击者可打开读取的任何文件的页缓存中执行受控的 4 字节写入:
该写入是可重复的 — 漏洞利用程序循环执行 4 字节写入,以修补更大的代码序列。
[1] Open /usr/bin/su (or any setuid-root binary) for reading ↓ [2] Map a copy to find target instruction bytes (e.g., UID check, execve path, security gate) ↓ [3] Compute exact page cache offset of target bytes ↓ [4] Set up AF_ALG socket → authencesn(hmac(sha256),cbc(aes)) ↓ [5] splice() the target binary's page cache into the socket ↓ [6] Trigger decryption → authencesn scratch write patches the target bytes in page cache (4 bytes per iteration) ↓ [7] Repeat for each 4-byte patch needed ↓ [8] Execute /usr/bin/su → runs root-owned setuid binary but now with attacker-controlled code in page cache ↓ [9] Root shell
### 3.5 为何标准防御措施会失效
| 防御措施 | 是否被绕过? | 原因 |
|---------|-----------|--------|
| 文件完整性监控(Tripwire/AIDE) | **是** | 磁盘上无任何更改 |
| IDS 文件哈希校验 | **是** | 磁盘字节未改变 |
| `inotify` 文件监视 | **是** | 无 VFS 写入事件 |
| SELinux / AppArmor | **部分** | 控制进程,而非通过加密引擎对页缓存的写入 |
| 只读挂载 | **是** | 页缓存在内存中被修改,而非通过挂载 |
| 对二进制文件的 auditd `watch` | **是** | 审计监视 VFS 写入——此攻击绕过了 VFS |
### 3.6 受影响的内核版本
| 分支 | 受影响版本 | 修复版本 |
|--------|-------------------|------------|
| 4.14.x | 全部(漏洞起源) | 无上游修复(已停止维护) |
| 5.4.x(LTS) | 全部 | 需发行版反向移植 |
| 5.10.x(LTS) | 全部 | 需发行版反向移植 |
| 5.15.x(LTS) | 全部 | 需发行版反向移植 |
| 6.1.x(LTS) | ≤ 6.1.129 | **6.1.130+** |
| 6.6.x(LTS) | ≤ 6.6.86 | **6.6.87+** |
| 6.12.x(LTS) | ≤ 6.12.22 | **6.12.23+** |
| 6.15-rc | 已在 rc 中修复 | **6.15-rc+** |
> 发行版内核可能以不同的版本号反向移植了修复。请始终查看您所用发行版的安全公告。
---
## 4. 攻击方法论——红队
> **需要授权。** 本节旨在帮助防御者理解攻击者的视角。仅可在您拥有或获得明确书面授权测试的系统上执行。
### 4.1 前提条件
- 目标上的低权限 shell(SSH、容器 exec、RCE 链)
- Python 3.10+ **或** 编译好的 C 二进制文件
- 未修补且具备 `algif_aead` 的内核
### 4.2 侦察```bash
# Check if vulnerable
uname -r
cat /proc/crypto | grep -A10 "authencesn"
lsmod | grep algif_aead
# Verify setuid target exists
ls -la /usr/bin/su /usr/bin/sudo /usr/bin/passwd
原始研究人员(Theori)发布了一个功能完整的 732 字节独立 Python PoC:
python3 copy_fail_exp.py
python3 copy_fail_exp.py /usr/bin/passwd
本地副本位于 `exploit/poc.py`。技术细节分析请参阅 `exploit/README.md`。
### 4.4 容器逃逸场景
由于 Linux 页缓存在同一主机上的所有进程(包括主机与容器)之间共享:```
Attacker in container → patches /usr/bin/su in HOST page cache
Host user runs su → executes attacker code as root on host
This works even from non-privileged containers, as long as the host kernel is vulnerable.
这是本仓库的主要关注点。
在任何 Linux 系统上运行检测脚本:```bash chmod +x detection/check_vulnerable.sh sudo ./detection/check_vulnerable.sh
**检查内容:**
- 内核版本是否处于已知受影响范围内
- `algif_aead` 模块的加载状态及黑名单状态
- `/proc/crypto` 中 `authencesn` 的可用性
- setuid 二进制文件的页缓存完整性(需要 root 权限)
- 各发行版特定的补丁状态
- 运行中的进程是否存在活跃利用迹象
带时间戳的报告将保存至 `/tmp/cve-2026-31431-report-*.txt`。
### 5.2 YARA 检测
`detection/yara/` 目录下提供了两条 YARA 规则:
| 规则文件 | 用途 |
|-----------|---------|
| `cve_2026_31431_base.yar` | 精确匹配已知的公开 PoC |
| `cve_2026_31431_enhanced.yar` | 检测混淆、编译及变种利用 |```bash
# Install YARA
apt-get install yara # Debian/Ubuntu
dnf install yara # RHEL/Fedora
apk add yara # Alpine
# Scan running process executables
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /proc/*/exe 2>/dev/null
# Scan common dropper locations
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /home /tmp /var/tmp /dev/shm
# Scan uploaded files / quarantine
yara detection/yara/cve_2026_31431_base.yar <suspect_file>
为何增强规则至关重要:攻击者可能混淆公开的 Python PoC(对字符串进行 base64 编码、对算法名称进行 XOR 编码、编译为 C 二进制文件、剥离符号)。增强规则通过针对无法在不破坏漏洞利用的情况下移除的不变量来检测这些变体:
authescesn 作为算法名称splice() 来实现零拷贝页缓存访问38)部署到 /etc/audit/rules.d/cve-2026-31431.rules:```bash
-a always,exit -F arch=b64 -S socket -F a0=38 -k cve_2026_31431_afalg
-a always,exit -F arch=b64 -S splice -k cve_2026_31431_splice
-a always,exit -F arch=b64 -S init_module -S finit_module -k cve_2026_31431_modload
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -k cve_2026_31431_suid_exec
重新加载:```bash
augenrules --load && service auditd restart
查询利用尝试:```bash
ausearch -k cve_2026_31431_afalg --start today
ausearch -k cve_2026_31431_afalg -k cve_2026_31431_splice --start today
### 5.4 Falco / eBPF 检测
添加到 `/etc/falco/rules.d/cve-2026-31431.yaml`:```yaml
- rule: CVE-2026-31431 AF_ALG Socket Creation
desc: Detects unprivileged process creating AF_ALG socket (family 38) — required step for Copy Fail exploit
condition: >
syscall.type = socket and
evt.arg.domain = 38 and
not user.uid = 0 and
not proc.name in (known_crypto_daemons)
output: >
CVE-2026-31431 exploitation attempt - AF_ALG socket (user=%user.name
uid=%user.uid pid=%proc.pid cmd=%proc.cmdline)
priority: CRITICAL
tags: [cve-2026-31431, lpe, kernel, crypto]
- list: known_crypto_daemons
items: [strongswan, charon, pluto, openssl]
- rule: CVE-2026-31431 Splice After AF_ALG
desc: Detects splice() syscall shortly after AF_ALG socket creation — exploitation sequence
condition: >
syscall.type = splice and
not user.uid = 0 and
evt.elapsed < 5000000000
output: >
CVE-2026-31431 splice after AF_ALG socket (user=%user.name pid=%proc.pid)
priority: CRITICAL
tags: [cve-2026-31431, lpe]
由于该漏洞利用会在不写入磁盘的情况下修改页面缓存,因此标准的文件完整性监控(FIM)工具对此毫无察觉。此检查可检测正在进行的漏洞利用行为:```bash #!/bin/bash
SETUID_BINS=("/usr/bin/su" "/usr/bin/sudo" "/usr/bin/passwd")
for binary in "${SETUID_BINS[@]}"; do [[ -f "$binary" ]] || continue LIVE_HASH=$(sha256sum "$binary" | awk '{print $1}') echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null # flush page cache DISK_HASH=$(sha256sum "$binary" | awk '{print $1}') if [[ "$LIVE_HASH" != "$DISK_HASH" ]]; then echo "CRITICAL: Page cache tampering detected on $binary" echo " Pre-flush: $LIVE_HASH" echo " Post-flush: $DISK_HASH" else echo "OK: $binary page cache matches disk" fi done
> **生产说明:** `drop_caches` 会导致性能下降。请先在维护窗口或非关键系统上运行。
### 5.6 入侵指标(IoCs)
| IoC 类型 | 指标 | 置信度 |
|----------|-----------|-----------|
| 字符串(二进制/脚本) | `authencesn(hmac(sha256),cbc(aes))` | 高 |
| 十六进制字节 | `78 DA AB 77 F5 71 63 62 64 64`(zlib 载荷头) | 高 |
| 系统调用序列 | `socket(38,5,0)` → `bind()` → `splice()` | 高 |
| 网络 | 无 — 纯本地 | 不适用 |
| 文件 | 无磁盘写入(隐蔽性) | — |
| 进程 | 带有 AF_ALG 套接字的短生命周期 Python/C 进程 | 中 |
| 页缓存 | setuid 二进制页缓存 ≠ 磁盘哈希 | 严重 |
### 5.7 SIEM 检测查询
**Splunk(auditd 数据源):**```spl
index=linux_audit sourcetype=auditd action=SYSCALL syscall=socket a0="0x26"
| join pid [
search index=linux_audit sourcetype=auditd action=SYSCALL syscall=splice
]
| where (_time - join_time) < 30
| table _time host user pid cmd a0
| eval severity="CRITICAL"
Elastic KQL:```kql event.action: "SYSCALL" AND process.args: "socket" AND auditd.data.a0: "0x26" AND NOT user.id: "0"
**Microsoft Sentinel (KQL):**```kql
Syslog
| where Facility == "kern" or ProcessName == "audit"
| where SyslogMessage contains "socket" and SyslogMessage contains "a0=0x26"
| extend UserName = extract("uid=([0-9]+)", 1, SyslogMessage)
| where UserName != "0"
| project TimeGenerated, Computer, UserName, SyslogMessage
| order by TimeGenerated desc
运行自动化修补脚本:```bash chmod +x patch/patch.sh sudo ./patch/patch.sh
### 6.1 立即缓解措施(无需重启*)```bash
# Blacklist the module permanently
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
echo "install authencesn /bin/false" | sudo tee -a /etc/modprobe.d/disable-algif-aead.conf
# Unload if currently loaded
sudo rmmod algif_aead 2>/dev/null || echo "Not loaded — mitigation active after config"
# Verify
lsmod | grep algif_aead && echo "WARNING: still loaded — reboot needed" || echo "OK: not loaded"
*如果 algif_aead 已加载,则需重启系统才能使黑名单完全生效。
副作用: 通过 AF_ALG 使用内核 AEAD 接口的应用程序(较为少见——大多数使用 OpenSSL 用户空间)可能会失败。标准 TLS、磁盘加密和 VPN 工具通常不受影响。
kubectl get nodes -o wide
kubectl drain --ignore-daemonsets --delete-emptydir-data
kubectl uncordon
使用节点自动升级器(Karpenter、托管节点组)或在可用时进行集群节点池轮换。
### 6.4 补丁后验证```bash
# Re-run detection script
sudo ./detection/check_vulnerable.sh
# Quick manual verification
uname -r # confirm new kernel version
lsmod | grep algif_aead # should be empty
cat /proc/crypto | grep authencesn # should return nothing (or still listed but module blacklisted)
提供了一个最小的 Alpine Docker 实验环境,用于安全地测试检测工具。```bash cd lab/ docker compose up -d docker exec -it cve-2026-31431-lab /bin/sh
/cve-2026-31431/detection/check_vulnerable.sh
> **重要提示:** Docker 容器与宿主机共享内核。本实验测试的是**宿主机内核**的漏洞状态。漏洞结果反映的是实际宿主机系统——这是有意为之,以便进行真实评估。
如需使用特定易受攻击的内核版本进行隔离测试,请使用固定内核的专用虚拟机。有关虚拟机设置指南,请参阅 `lab/README.md`。
---
## 8. 参考资料
| 资源 | 链接 |
|----------|------|
| NVD 公告 | https://nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| 原始研究 | https://copy.fail |
| 技术文章 | https://xint.io/blog/copy-fail-linux-distributions |
| 公开 PoC | https://github.com/theori-io/copy-fail-CVE-2026-31431 |
| CISA KEV 目录 | https://www.cisa.gov/known-exploited-vulnerabilities-catalog |
| 内核修复 — 回滚提交 | `a664bf3d603d` / `fafe0fa2995a` |
| 易受攻击的提交 | `72548b093ee3` |
| Microsoft Defender 公告 | Microsoft Defender 威胁情报博客 |
---
## 仓库结构```
cve-2026-31431/
├── README.md ← This document
├── exploit/
│ ├── README.md ← Technical exploit breakdown
│ └── poc.py ← Public PoC (theori-io, for reference)
├── detection/
│ ├── README.md ← Detection guide
│ ├── check_vulnerable.sh ← Vulnerability & IoC detection script
│ └── yara/
│ ├── cve_2026_31431_base.yar ← Detects known public PoC
│ └── cve_2026_31431_enhanced.yar ← Detects obfuscated/compiled variants
├── patch/
│ ├── README.md ← Remediation guide
│ └── patch.sh ← Automated patch/mitigation script
└── lab/
├── README.md ← Lab setup guide
├── Dockerfile ← Alpine-based lab container
└── docker-compose.yml ← Lab orchestration
本研究仅供教育和防御性安全目的使用。所有工具旨在帮助防御者在经授权保护的系统中检测并修复CVE-2026-31431。
仓库由 rippsec 维护
| 属性 | 值 |
|---|
| 写入大小 | 4 字节 |
| 偏移控制 | 是 — 可通过 splice 偏移量由攻击者控制 |
| 目标 | 任何可读文件的页缓存 |
| 脏页标记 | 无 |
| 磁盘修改 | 无 |
| 时间戳更新 | 无 |
| 内核日志条目 | 无(除非配置了 auditd) |
| 技术 | ID | 备注 |
|---|
| 利用提权漏洞 | T1068 | 核心技术 |
| 滥用权限提升控制机制:Setuid/Setgid | T1548.001 | Setuid 二进制劫持 |
| 劫持执行流 | T1574 | 内存中二进制补丁 |
| 指标清除:时间戳篡改 | T1070.006 | 未更新时间戳 |
| 间接命令执行 | T1202 | 打补丁的二进制执行 shell |
| 发行版 | 更新命令 |
|---|
| Ubuntu / Debian | apt-get update && apt-get upgrade linux-image-generic && reboot |
| RHEL / CentOS / Rocky | dnf update kernel && reboot |
| Amazon Linux 2 | yum update kernel && reboot |
| Amazon Linux 2023 | dnf update kernel && reboot |
| SUSE / SLES | zypper update kernel-default && reboot |
| Arch Linux | pacman -Syu linux && reboot |
| Alpine Linux | apk update && apk upgrade linux-lts && reboot |
| Debian | apt-get update && apt-get upgrade linux-image-amd64 && reboot |