一、先搞懂基础:这是什么漏洞?
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常见概念:
-
页缓存(Page Cache):Linux为了减少磁盘读写,会把经常用的文件先放到内存里,后面程序读文件直接读内存里的副本,速度更快。这个内存副本就是页缓存,默认是可读的,正常程序不能随便改它。
-
AF_ALG套接字:Linux内核给用户态程序开放的"调用内核加密能力"的标准接口,普通用户不用root就能用,比如程序要做AES加密,不用自己写算法,直接走这个接口让内核帮忙算。
-
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基本都能跑。
三、怎么复现?(仅供授权测试环境使用,勿用于未授权设备)
前置条件
-
测试机内核版本在4.14 ~ 6.18.22/6.19.12/7.0之前,未打补丁;
-
普通用户权限(不需要sudo);
-
Python3.1.3及以上版本;
-
内核加载了
algif_aead模块(大部分默认发行版都开了)。
复现步骤
-
准备环境 :开一台未打补丁的Ubuntu 22.04/24.04虚拟机,新建普通用户
test,切换过去,先执行id,显示uid=1000(test)就是普通权限。 -
获取EXP :公开EXP地址是
https://github.com/theori-io/copy-fail-CVE-2026-31431,下载exp.py传到测试机/tmp目录。(⚠️ 提醒:测试前最好备份/usr/bin/su,避免改坏无法恢复) -
执行EXP :普通用户下运行
python3 /tmp/exp.py,等待几秒后如果看到新的shell提示符,再执行id,显示uid=0(root)就提权成功了。
复现注意事项
-
如果提示找不到
algif_aead模块,先执行sudo modprobe algif_aead加载(仅测试环境用); -
部分定制内核可能禁用了AF_ALG接口,这种情况漏洞无法触发;
-
测试完建议立刻还原
/usr/bin/su或者升级内核,避免留后门。
四、影响范围与危害
-
本地提权:任何有普通用户权限的人都能拿root,多用户服务器、开发机、跳板机风险极高;
-
容器逃逸 :页缓存是宿主机和所有容器共享的,容器里普通用户触发漏洞,能改宿主机的
su页缓存,直接逃出容器拿下宿主机root; -
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模块,阻止漏洞触发路径:
bash
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null
注意:部分依赖内核加密加速的程序可能会降级到用户态加密,有轻微性能影响,只是临时方案。
给初学者的小提示
这个是很好的内核漏洞入门案例:它不需要你懂复杂的堆溢出、ROP链,核心是"多个看似没问题的逻辑拼到一起出了错",也是真实世界漏洞最常见的形态。如果想深入学,可以去看看官方补丁:就是把那个"原地优化"改回分开的输入输出缓冲区,从根源上避免页缓存被当可写缓冲区。
⚠️ 本文仅用于安全研究学习,请勿对未授权系统进行测试,触发漏洞可能违反法律法规。