一、先搞懂基础:这是什么漏洞?

CVE-2026-31431 代号叫 Copy Fail,是2026年公开的Linux内核高危本地提权漏洞,CVSS评分7.8(高危)。它的核心特点是:不需要复杂的竞争条件、不需要编译复杂EXP、用一个700多字节的Python脚本就能稳定把普通用户提权到root,甚至还能用来做容器逃逸,影响2017年到2026年修复前几乎所有主流Linux发行版(Ubuntu、RHEL、Amazon Linux、Debian、国产欧拉/UOS/麒麟等)。

二、漏洞原理(大白话版,不用啃内核代码也能懂)

要理解这个漏洞,我们先拆解3个Linux常见概念:

  1. 页缓存(Page Cache):Linux为了减少磁盘读写,会把经常用的文件先放到内存里,后面程序读文件直接读内存里的副本,速度更快。这个内存副本就是页缓存,默认是可读的,正常程序不能随便改它。

  2. AF_ALG套接字:Linux内核给用户态程序开放的“调用内核加密能力”的标准接口,普通用户不用root就能用,比如程序要做AES加密,不用自己写算法,直接走这个接口让内核帮忙算。

  3. splice系统调用:Linux的“零拷贝”传输工具,传文件的时候不用把数据拷到用户内存,直接把磁盘页缓存的引用传给目标,效率很高。

漏洞怎么来的?

2017年Linux内核给algif_aead(AF_ALG下的认证加密模块)加了“原地操作优化”:本来加密解密要分开输入输出缓冲区,这个优化让输入和输出用同一个缓冲区,省得拷贝。但这个优化有个疏忽:

当你用splice把某个可读文件(比如有setuid权限的/usr/bin/su,普通用户执行它会自动拿到root权限)的页缓存直接塞给AF_ALG套接字时,内核会错误地把只读的页缓存页面,当成了可写的解密输出缓冲区

然后触发authencesn加密模板的解密流程时,程序会往缓冲区里固定位置写4个字节的临时数据——哪怕后面解密失败了,这4个字节也已经实实在在改了页缓存的内容。

为什么能提权?

/usr/bin/su是有setuid位的:只要普通用户运行它,进程会自动升到root权限。我们改了内存里的su页缓存,下次用户运行su的时候,内核直接读被篡改的页缓存副本(不会去读磁盘上没改的原始文件),相当于运行了我们植入的恶意代码,自然就拿到了root权限。

这个漏洞有多“离谱”?

  • 不像老牌的Dirty Cow(脏牛)漏洞要靠运气抢竞争窗口,这个是100%确定性触发,跑一次就成,不会崩系统;

  • 改的是内存页缓存,不会回写磁盘,所以你查su文件的哈希值、用文件完整性工具都发现不了异常,特别隐蔽;

  • EXP只有732字节Python脚本,不用编译,只要是带Python的Linux基本都能跑。

三、怎么复现?(仅供授权测试环境使用,勿用于未授权设备)

前置条件

  1. 测试机内核版本在4.14 ~ 6.18.22/6.19.12/7.0之前,未打补丁;

  2. 普通用户权限(不需要sudo);

  3. Python3.1.3及以上版本;

  4. 内核加载了algif_aead模块(大部分默认发行版都开了)。

复现步骤

  1. 准备环境:开一台未打补丁的Ubuntu 22.04/24.04虚拟机,新建普通用户test,切换过去,先执行id,显示uid=1000(test)就是普通权限。

  2. 获取EXP:公开EXP地址是https://github.com/theori-io/copy-fail-CVE-2026-31431,下载exp.py传到测试机/tmp目录。(⚠️ 提醒:测试前最好备份/usr/bin/su,避免改坏无法恢复)

  3. 执行EXP:普通用户下运行python3 /tmp/exp.py,等待几秒后如果看到新的shell提示符,再执行id,显示uid=0(root)就提权成功了。

复现注意事项

  • 如果提示找不到algif_aead模块,先执行sudo modprobe algif_aead加载(仅测试环境用);

  • 部分定制内核可能禁用了AF_ALG接口,这种情况漏洞无法触发;

  • 测试完建议立刻还原/usr/bin/su或者升级内核,避免留后门。

四、影响范围与危害

  1. 本地提权:任何有普通用户权限的人都能拿root,多用户服务器、开发机、跳板机风险极高;

  2. 容器逃逸:页缓存是宿主机和所有容器共享的,容器里普通用户触发漏洞,能改宿主机的su页缓存,直接逃出容器拿下宿主机root;

  3. CI/CD/云环境风险:GitHub Actions、GitLab Runner、Serverless这类多租户环境,恶意代码提交就能提权到节点root,影响同节点所有用户。

五、修复与临时缓解

彻底修复(首选)

升级内核到修复版本:

  • 主线内核 ≥7.0

  • 6.18分支 ≥6.18.22

  • 6.19分支 ≥6.19.12

    各发行版(Ubuntu/RHEL/SUSE/欧拉等)都已推送安全更新,直接apt upgrade/dnf update kernel后重启即可。

临时缓解(暂时不能重启的场景)

禁用algif_aead模块,阻止漏洞触发路径:

echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null

注意:部分依赖内核加密加速的程序可能会降级到用户态加密,有轻微性能影响,只是临时方案。

给初学者的小提示

这个是很好的内核漏洞入门案例:它不需要你懂复杂的堆溢出、ROP链,核心是“多个看似没问题的逻辑拼到一起出了错”,也是真实世界漏洞最常见的形态。如果想深入学,可以去看看官方补丁:就是把那个“原地优化”改回分开的输入输出缓冲区,从根源上避免页缓存被当可写缓冲区。

⚠️ 本文仅用于安全研究学习,请勿对未授权系统进行测试,触发漏洞可能违反法律法规。

Logo

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

更多推荐