rippsec/cve-2026-31431

GitHub: rippsec/cve-2026-31431

针对 Linux 内核 algif_aead 高危本地提权漏洞 CVE-2026-31431 的综合性安全研究仓库,提供漏洞利用分析、检测规则、自动化修复脚本和隔离实验环境。

Stars: 1 | Forks: 0

# CVE-2026-31431 — "Copy Fail":Linux 内核 `algif_aead` 本地权限提升 ## 目录 1. [执行摘要](#1-executive-summary) 2. [风险评估](#2-risk-assessment) 3. [技术深入探讨](#3-technical-deep-dive) 4. [攻击方法论 — 红队](#4-attack-methodology--red-team) 5. [检测与事件响应 — 蓝队](#5-detection--incident-response--blue-team) 6. [补丁与修复](#6-patching--remediation) 7. [实验环境](#7-lab-environment) 8. [参考链接](#8-references) ## 1. 执行摘要 **CVE-2026-31431**,绰号 **"Copy Fail"**,是 Linux 内核加密子系统中的一个高危本地权限提升(LPE)漏洞。低权限的本地用户可以在几秒钟内在任何未修补的系统上提权至 **root**。 | 属性 | 值 | |-----------|-------| | CVE | CVE-2026-31431 | | 绰号 | Copy Fail | | CVSS v3.1 | **7.8 HIGH** | | 攻击向量 | 本地 | | 所需权限 | 低 | | 用户交互 | 无 | | 组件 | `crypto/algif_aead.c` — `authencesn` 模板 | | 引入时间 | 2017 (commit `72548b093ee3`) | | 披露时间 | 2026 | | 潜伏期 | ~9 年 | | CISA KEV | **是** | | 公开 PoC | **是** (732 字节独立 Python 脚本) | ### 业务影响 - 在任何未修补的 Linux 服务器、虚拟机、云实例或容器宿主机上获得 **root 权限** - 从 Kubernetes Pod 实现 **容器逃逸** — 页面缓存与宿主机内核共享 - **零磁盘痕迹** — 利用过程不会留下文件更改、脏页,也无法通过标准文件完整性工具(Tripwire, AIDE)追踪审计记录 - 影响 **Red Hat、Ubuntu、Debian、SUSE、Amazon Linux** 以及几乎所有运行 2017 年及以后内核的主流发行版 ### 建议立即采取的行动 1. **临时缓解措施**(立即部署,如果模块未加载则不需要重启): echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf sudo rmmod algif_aead 2>/dev/null || true 2. **永久修复**:通过发行版的包管理器更新内核包并重启。 3. **验证**:在修复前后运行 `detection/check_vulnerable.sh`。 ## 2. 风险评估 ### CVSS 3.1 向量字符串 ``` CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H ``` | 指标 | 值 | 理由 | |--------|-------|-----------| | 攻击向量 | **本地** | 需要 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 年,commit `72548b093ee3` 作为性能优化,向 `algif_aead` 引入了**原地 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. ``` ### 3.3 写入原语 该漏洞提供了一个**向攻击者可打开读取的任何文件的页面缓存中进行受控 4 字节写入**的原语: | 属性 | 值 | |----------|-------| | 写入大小 | 4 字节 | | 偏移控制 | 是 — 通过 splice 偏移量由攻击者控制 | | 目标 | 任何可读文件的页面缓存 | | 脏页标记 | **无** | | 磁盘修改 | **无** | | 时间戳更新 | **无** | | 内核日志条目 | 无(除非配置了 auditd) | 写入是可重复的 — 该漏洞利用程序循环执行 4 字节写入以修补更大的代码序列。 ### 3.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` | **是** | Audit 监控 VFS 写入 — 此操作绕过了 VFS | ### 3.6 受影响的内核版本 | 分支 | 受影响版本至 | 修复起始版本 | |--------|-------------------|------------| | 4.14.x | 所有版本(漏洞起源) | 无上游修复(已 EOL) | | 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 侦察 ``` # 检查是否存在漏洞 uname -r cat /proc/crypto | grep -A10 "authencesn" lsmod | grep algif_aead # 验证 setuid 目标是否存在 ls -la /usr/bin/su /usr/bin/sudo /usr/bin/passwd ``` ### 4.3 公开 PoC 原始研究人员(Theori)发布了一个完全可用的 732 字节独立 Python PoC: - **代码库**:https://github.com/theori-io/copy-fail-CVE-2026-31431 - **网站**:https://copy.fail - **文件**:`copy_fail_exp.py` ``` # 默认:目标 /usr/bin/su 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 ``` 只要宿主机内核存在漏洞,即使是非特权容器也可以成功利用。 ### 4.5 MITRE ATT&CK 映射 | 技术 | ID | 备注 | |-----------|-----|-------| | 利用漏洞进行权限提升 | T1068 | 核心技术 | | 滥用提升控制机制:Setuid/Setgid | T1548.001 | Setuid 二进制文件劫持 | | 劫持执行流 | T1574 | 内存中二进制文件修补 | | 指标移除:时间戳伪造 | T1070.006 | 未更新时间戳 | | 间接命令执行 | T1202 | 被修补的二进制文件执行 shell | ## 5. 检测与事件响应 — 蓝队 ### 5.1 漏洞检测 在任何 Linux 系统上运行检测脚本: ``` 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` | 检测混淆、编译和变体漏洞利用 | ``` # 安装 YARA apt-get install yara # Debian/Ubuntu dnf install yara # RHEL/Fedora apk add yara # Alpine # 扫描运行中进程的可执行文件 sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /proc/*/exe 2>/dev/null # 扫描常见投放位置 sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /home /tmp /var/tmp /dev/shm # 扫描上传文件 / 隔离区 yara detection/yara/cve_2026_31431_base.yar ``` **为什么增强规则很重要**:攻击者可能会混淆公开的 Python PoC(base64 编码字符串、XOR 编码算法名称、编译为 C 二进制文件、剥离符号)。增强规则通过定位那些在不破坏漏洞利用的情况下无法移除的不变量来检测这些变体: - 内核必须接收 `authencesn` 作为算法名称 - 漏洞利用必须使用 `splice()` 来实现零拷贝页面缓存访问 - 漏洞利用必须创建一个 AF_ALG 套接字(family `38`) ### 5.3 Auditd 规则 部署到 `/etc/audit/rules.d/cve-2026-31431.rules`: ``` # 检测 AF_ALG socket 创建 (family 38 = 0x26) -a always,exit -F arch=b64 -S socket -F a0=38 -k cve_2026_31431_afalg # 检测 splice() 调用 — 用于将 page cache 送入 socket -a always,exit -F arch=b64 -S splice -k cve_2026_31431_splice # 监控 algif_aead 模块加载 -a always,exit -F arch=b64 -S init_module -S finit_module -k cve_2026_31431_modload # 检测非 root 用户执行 setuid 二进制文件 -a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -k cve_2026_31431_suid_exec ``` 重新加载: ``` augenrules --load && service auditd restart ``` 查询利用尝试: ``` # 查找 AF_ALG socket 创建 ausearch -k cve_2026_31431_afalg --start today # 关联:同一 PID 执行 AF_ALG socket + splice 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`: ``` - 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] ``` ### 5.5 页面缓存完整性检查 由于该漏洞在**不写入磁盘**的情况下修改了页面缓存,标准的 FIM 工具是盲目的。此检查可检测活动利用: ``` #!/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 ``` ### 5.6 妥协指标 | IoC 类型 | 指标 | 置信度 | |----------|-----------|-----------| | 字符串(二进制文件/脚本) | `authencesn(hmac(sha256),cbc(aes))` | 高 | | 十六进制字节 | `78 DA AB 77 F5 71 63 62 64 64` (zlib 载荷头) | 高 | | 系统调用序列 | `socket(38,5,0)` → `bind()` → `splice()` | 高 | | 网络 | 无 — 纯本地 | N/A | | 文件 | 无磁盘写入(隐蔽) | — | | 进程 | 具有 AF_ALG 套接字的短期 Python/C 进程 | 中 | | 页面缓存 | setuid 二进制文件页面缓存 ≠ 磁盘哈希 | 严重 | ### 5.7 SIEM 检测查询 **Splunk(auditd 源):** _BLOCK_13/> **Elastic KQL:** ``` event.action: "SYSCALL" AND process.args: "socket" AND auditd.data.a0: "0x26" AND NOT user.id: "0" ``` **Microsoft Sentinel (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 ``` ## 6. 补丁与修复 运行自动化补丁脚本: ``` chmod +x patch/patch.sh sudo ./patch/patch.sh ``` ### 6.1 立即缓解(无需重启*) ``` # 永久将模块加入黑名单 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 # 若当前已加载则卸载 sudo rmmod algif_aead 2>/dev/null || echo "Not loaded — mitigation active after config" # 验证 lsmod | grep algif_aead && echo "WARNING: still loaded — reboot needed" || echo "OK: not loaded" ``` *如果 `algif_aead` 已加载,则需要重启才能使黑名单完全生效。 **副作用**:通过 AF_ALG 使用内核 AEAD 接口的应用程序(不常见 — 大多数使用 OpenSSL 用户空间)可能会失败。标准的 TLS、磁盘加密和 VPN 工具通常不受影响。 ### 6.2 永久修复 — 内核更新 | 发行版 | 更新命令 | |---|---| | 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` | ### 6.3 Kubernetes 集群 ``` # 检查所有节点内核版本 kubectl get nodes -o wide # 排空 → 更新节点内核 → 恢复调度 (每次一个节点) kubectl drain --ignore-daemonsets --delete-emptydir-data # SSH 进入节点并运行内核更新 kubectl uncordon ``` 在可用的情况下,使用节点自动升级器(Karpenter、托管节点组)或集群节点池轮换。 ### 6.4 补丁后验证 ``` # 重新运行检测脚本 sudo ./detection/check_vulnerable.sh # 快速手动验证 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) ``` ## 7. 实验环境 提供了一个基于 Alpine Docker 的最小化实验环境,用于安全测试检测工具。 ``` cd lab/ docker compose up -d docker exec -it cve-2026-31431-lab /bin/sh # 在容器内: /cve-2026-31431/detection/check_vulnerable.sh ``` 要使用特定的易受攻击内核版本进行隔离测试,请使用固定了内核版本的专用虚拟机。有关虚拟机设置的指南,请参见 `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 Threat Intelligence Blog | ## 代码库结构 ``` 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](https://github.com/rippsec) 维护*
标签:algif_aead, CISA KEV, Copy Fail, Cutter, CVE-2026-31431, DNS信息、DNS暴力破解, Docker镜像, Linux内核漏洞, LPE, PoC, Python, Web报告查看器, YARA规则, 子域名枚举, 安全渗透, 容器逃逸, 密码学子系统, 无后门, 暴力破解, 本地权限提升, 检测工具, 漏洞分析, 系统安全, 网络安全, 补丁修复, 请求拦截, 路径探测, 逆向工具, 隐私保护