无声处听惊雷|CopyFail漏洞深度拆解

admin 2026-05-02 05:16:06 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: CopyFail漏洞影响9年的Linux内核,源于零拷贝页面来源混淆。普通用户仅用10行Python即可100%稳定提权与容器逃逸,因仅改内存绕过HIDS检测。建议立即禁用algif_aead模块并打补丁重启,同时利用AI辅助暴露面评估与syscall异常监控。 综合评分: 96 文章分类: 漏洞分析,二进制安全,应急响应,AI安全,内网渗透


2026 年 4 月 29 日,韩国安全公司 Theori 的研究员 Taeyang Lee 公开了一个 Linux 内核漏洞的完整利用细节。这个漏洞被命名为 Copy Fail,编号 CVE-2026-31431。

说直白一点:任何能登录 Linux 服务器的普通用户,跑一个 10 行的 Python 脚本,就能拿到 root 权限。

不需要猜密码,不需要利用配置错误,不需要任何特殊条件。这个脚本只有 732 字节,用的是 Python 标准库,不依赖任何第三方工具。同一个脚本在 Ubuntu、RHEL、Amazon Linux、SUSE 上均测试成功,无需任何修改

更要命的是,这个漏洞从 2017 年就存在了。整整潜伏了 9 年。

二、技术原理拆解

三个“合理”的设计决策,交叉在一起就炸了。

攻击者完全控制三个变量:

  • 写哪个文件 → 任意当前用户可读文件(如 /usr/bin/su)

  • 写哪个偏移 → 通过调整 splice 参数精确控制

  • 写什么值 → AAD 的第 4-7 字节,攻击者构造

req->src / req->dst (就地操作)AADCT用户缓冲区(安全)chainTag (page cache 页面)来自 splice 的文件缓存authencesn 在此写入 4 字节直接篡改目标文件内存映像用户态缓冲区(合法写入范围)Page cache 页面(被越界写入)

图:in-place 模式下的内存布局。authencesn 的越界写入穿过合法缓冲区,落入 page cache 页面。

三、为什么这次不一样

和历史上的 Dirty Cow、Dirty Pipe 正面对比:

| 维度 | Dirty Cow (2016) | Dirty Pipe (2022) | Copy Fail (2026) | | — | — | — | — | | 竞争条件 | 需要,反复重试 | 不需要 | 不需要,纯逻辑 | | 版本范围 | 较广 | 5.8~5.16,很窄 | 4.14+,9 年全部 | | 稳定性 | 中等,可能 panic | 较好 | 100% 成功 | | 隐蔽性 | 低,页面被标记 dirty 最终回写磁盘可检测 | 中等 | 极高,只改内存 | | 容器逃逸 | 有限 | 理论可行 | 天然支持 | | PoC 大小 | ~150 行 C | ~100 行 C | 10 行 Python |

四、利用链路

整个提权过程四步完成:

❶ 打开加密通道:

创建 AF_ALG socket,绑定 authencesn(hmac(sha256),cbc(aes))。设置密钥,接受请求连接。全程不需要任何特权。

❷ 构造写入原语

通过 sendmsg() 构造 AAD(第 4-7 字节为目标写入值)。通过 splice() 将 /usr/bin/su 的 page cache 页面送入 socket。精确计算偏移,使越界写入落在 .text 段目标位置。

❸ 触发越界写入

调用 recv() 触发解密。authencesn 将 4 字节 seqno_lo 写入 page cache 页面。HMAC 校验失败,返回错误,但page cache 已经被篡改。循环此过程,逐 4 字节注入 shellcode。

❹ 执行 → Root

调用 execve("/usr/bin/su")。内核从 page cache 加载——加载的是篡改后的版本。因为 su 是 setuid root,注入的 shellcode 以 UID 0 运行。游戏结束。

已验证可利用的环境:Ubuntu 24.04 LTS(Kernel 6.17)、Amazon Linux 2023(Kernel 6.18)、RHEL 10.1(Kernel 6.12)、SUSE 16(Kernel 6.12)。同一个脚本,无需任何修改。

注:PoC 使用了 os.splice(Python 3.10+ 新增 API)。低于 3.10 的 Python 版本无法直接运行原始 PoC,但已有社区移植版本通过 ctypes 调用 libc splice 实现了对旧版 Python 的兼容。

五、影响范围

一句话判断:如果你运行的是 2017 年之后发布的主流 Linux 内核(4.14+)且没打补丁,就假设自己是受影响的。唯一的例外是那些不包含该漏洞代码的古老版本(如 RHEL 6/7,内核未引入相关 commit)。

六、时间线

七、深入:现有报道没告诉你的事

大多数报道停留在”漏洞很严重、赶紧打补丁”。但如果你真的想理解这件事的全貌,有几个维度需要进一步拆开看。

❶ 检测困境比想象中更深

文章前面提到 AIDE/Tripwire 检测不到。但问题不止于此。

Linux 的 IMA(Integrity Measurement Architecture)是更高级的运行时完整性方案。理论上,在 appraise 模式下,IMA 会在文件执行时计算当前哈希并与存储在 xattr 中的参考哈希对比。但即便启用了 appraise 模式,IMA 也并非万无一失:它会将 appraise 结果缓存在内核的 iint 结构中,后续执行直接复用缓存,不再重新计算哈希。缓存失效依赖 i_version 变化(即通过 VFS 写入路径修改文件时触发),而 Copy Fail 的 page cache 篡改完全绕过了 VFS,不会触发 i_version 更新,IMA 的缓存也就不会失效。对于 /usr/bin/su 这类系统启动后通常已被执行(appraise)过的二进制,IMA 会直接使用缓存的”通过”结果。只有在文件从未被 appraise 过的冷启动场景下,IMA 才可能检测到异常。更何况,绝大多数生产环境根本没有启用 IMA appraise 模式(配置复杂且可能干扰正常运维)。常见的 measure-only 模式只是将哈希记录到 PCR 日志中,不会阻止执行,也不会主动告警。

至于 dm-verity,它在块设备层面验证数据完整性,但只在数据块从磁盘加载进 page cache 的那一刻做校验。如果篡改发生在块加载之后(Copy Fail 正是这种情况),后续从 page cache 的读取不会再经过 dm-verity,同样检测不到

换句话说:当前主流 Linux 生态中没有开箱即用的方案能可靠阻止 page cache 级别的篡改。IMA appraise 最接近,但受限于缓存机制,对已运行过的二进制同样失效。这是一个系统性的盲区。

❷ 持久化的局限性与攻击者的变通

Copy Fail 的篡改只存在于 page cache 中。一旦内存压力导致页面被淘汰,或者系统重启,篡改就消失了。所以这不是一个直接的持久化后门

但攻击者不会止步于此。拿到 root 之后:

  • 可以篡改 /etc/crontab~/.bashrc、systemd unit 等配置文件的 page cache,植入反向 shell,等系统自动执行完成持久化

  • 可以直接写磁盘安装传统 rootkit,因为此时已经是 root

  • 在容器场景中,可以篡改宿主机上的关键二进制,影响该节点上的所有 Pod

Copy Fail 本身是提权原语,提权之后的持久化手段不受此限制。

❸ 还有未公开的漏洞

Xint 原文中有一句值得高度关注的话:

“The scan also identified other high severity vulnerabilities, including another privilege escalation bug. These other bugs are still in the responsible disclosure process.”

—— Xint 博客原文

这意味着同一个子系统(crypto/)中至少还有一个已确认的高危提权漏洞尚未公开。当前的补丁只修复了 Copy Fail 这一个点。如果你的缓解策略只是”禁用 algif_aead”,可能不足以覆盖后续披露的漏洞。更稳妥的做法是从 AF_ALG socket 层面整体限制。

❹ 补丁的局限性

当前补丁 a664bf3d603d 的修复方式是回退 in-place 优化,恢复 out-of-place 操作。这确实消除了 Copy Fail 的利用路径,但值得注意的是:

  • 补丁没有修改 authencesn 的越界写入行为本身——它仍然会在 dst[assoclen + cryptlen] 位置写入草稿数据
  • 补丁没有在内核层面引入 page 来源追踪机制——scatterlist 中的页面是来自用户内存还是 page cache,内核仍然不做区分

修复是对症下药,但病根(page 来源不透明)并未根治。未来如果有其他代码路径再次将 page cache 页面放入可写 scatterlist,同类问题还会出现。

八、延伸:同一模式下的其他攻击面

Copy Fail 的本质是一种「页面来源混淆」(Page Provenance Confusion)漏洞:零拷贝机制将 page cache 页面的引用传入了一个假设自己拥有写权限的子系统。这不是个案,而是一整类攻击面。

沿着这条线索推演,以下方向值得系统性审视:

❶ AF_ALG 的其他算法模板

Copy Fail 利用的是 authencesn,但 AF_ALG 支持数十种算法模板。理论上,任何在解密/处理路径中对输入 scatterlist 进行了超出合法范围写入的算法,都可能产生类似漏洞。值得审计的候选者包括:

  • pcrypt(并行加密包装器)——内部调度可能有缓冲区复用

  • gcm 的某些变体——GHash 计算涉及 AAD 处理

  • ccm——CBC-MAC 计算过程中的中间状态写入

Xint 已确认在同一子系统中发现了其他高危漏洞,这进一步验证了这个方向的价值。

❷ splice() 的其他内核消费端

AF_ALG 只是 splice() 的消费端之一。splice 还可以将 page cache 页面送入:

  • 网络子系统——sendfile() 底层就是 splice,网络协议栈中的缓冲区操作是否会回写源页面?

  • 设备驱动——某些字符设备、块设备驱动接受 splice 输入

  • FUSE——用户态文件系统与 splice 交互时,page cache 页面如何流转?

核心问题:所有接受 splice 输入的内核代码,是否都正确假设了源页面可能是只读的 page cache?大概率不是。

❸ io_uring + splice 的组合

io_uring 有自己的 splice 实现(IORING_OP_SPLICE),并且是近年来内核漏洞的高发区。它的异步特性引入了额外的复杂性:

  • 异步 splice 操作的页面生命周期管理更复杂,竞争窗口更多

  • io_uring 的 fixed buffer(IORING_OP_PROVIDE_BUFFERS)与 page cache 页面的交互尚未被充分审计

  • io_uring 已有大量 CVE 记录,但多数集中在 UAF 和竞争条件,page 来源混淆方向的审计几乎是空白

❹ vmsplice() 的历史回眸

2008 年的 vmsplice() 漏洞(CVE-2008-0600)是同一类问题的早期版本:用户态传入的页面引用被内核错误地信任。虽然那个具体漏洞早已修复,但 vmsplice() 的代码路径在过去十几年里经历了多次重构,是否在新代码中重新引入了类似的页面引用混淆?值得重新审视。

❺ 零拷贝与 DMA-BUF 共享内存

更广义地看,所有涉及跨子系统的页面引用传递的内核机制都可能存在类似问题:

  • MSG_ZEROCOPY —— 零拷贝发送涉及用户页面的生命周期管理

  • AF_XDP —— 高性能网络路径中的页面池共享

  • DMA-BUF —— GPU/显示子系统的共享缓冲区机制,在多设备间传递页面引用

这些场景的共性是:页面的来源(用户内存、page cache、设备 DMA 区域)在传递过程中丢失了,而消费端对页面的读写权限做了错误假设。

❻ 系统性结论

Copy Fail 暴露的不是一个孤立的 bug,而是 Linux 内核中一个结构性的设计盲区:内核没有对 scatterlist / bio / pipe buffer中的页面标记来源属性。一个来自 page cache 的只读页面和一个来自用户空间的可写页面,在 scatterlist 中看起来完全一样。

只要这个根本问题不解决,每当有新的零拷贝路径被引入(而内核在持续增加这类优化),同类漏洞就有再次出现的可能。

Copy Fail 是这类漏洞的标志性案例,但大概率不是最后一个。

九、安全运营视角:AI 能帮上什么忙?

Copy Fail 不只是一个漏洞分析的对象,它也是安全运营能力的一面镜子。从收到通告到完成缓解,整个过程中有哪些环节可以用 AI 加速?不讲万能论,逐个场景说。

❶ 可实施:AI 辅助漏洞发现

Copy Fail 本身就是最好的例证。Theori 研究员 Taeyang Lee 明确提到借助 Xint Code AI 做的代码扫描。这不是事后蹭热度——AI 确实在审计中发现了人工极难捕捉的跨模块逻辑漏洞。

这类漏洞的特点是每一段代码单独看都没问题。AF_ALG 暴露给用户态是合理的,splice 的零拷贝是合理的,authencesn 的 ESN 写入也有其上下文。人工审计很难同时跟踪三个子系统的数据流,但 AI 做全代码库级别的 taint analysis 和 dataflow tracking 有天然优势。

对安全团队的启示:如果你的组织有自研内核模块、驱动或底层系统组件,用 AI 做变体分析(variant analysis)是投入产出比很高的事。以 Copy Fail 为例,可以让 AI 扫描所有 splice_read / splice_write 的消费端,检查是否存在”将 page cache 页面引用传入可写路径”的同类模式。

❷ 可落地:应急响应自动化

Copy Fail 应急的最大痛点是暴露面评估慢。安全运营需要快速回答:我有多少台机器内核 >= 4.14?哪些加载了 algif_aead 模块?哪些 K8s 节点的 Pod 有 hostPath 挂载?我的 seccomp profile 是否拦截了 AF_ALG?

这些问题本身不难,但在数千台机器的环境里,人工操作通常需要几个小时到一天。AI 可以做的事:把非结构化的漏洞通告转化为结构化的查询逻辑。给 AI 一份 CVE 描述,它可以生成 osquery 查询、Ansible playbook、或者 CMDB 过滤条件。

理想的自动化链路:CVE feed → AI 解析影响条件 → 自动查询资产管理系统 → 生成受影响清单 + 缓解脚本 → 推送给对应负责人。从小时级压缩到分钟级,在 PoC 已公开、补丁未就绪的窗口期里,这个时间差就是你的防线。

❸ 有价值但需要基础设施:运行时异常检测

// 利用链的 syscall 序列(正常业务中几乎不会出现)socket(AF_ALG, ...)         // 极少有用户态程序使用bind("authencesn(...)")     // 更罕见splice(目标文件fd, ...)      // 把 setuid 二进制送入加密 socket?recv(...)                   // 触发越界写入

绝大多数 Linux 服务器上没有任何用户态程序会打开 AF_ALG socket,更不会用 splice 把一个 setuid 二进制的 fd 送进加密 socket。

AI 在这里的角色:基于 eBPF 或 audit 日志做 syscall 序列异常建模。不需要精确匹配已知 PoC——训练模型识别”异常的 socket 类型 + 异常的 splice 目标组合”,就能覆盖变体攻击。如果你已经部署了 Falco、Tetragon 或自研的 eBPF 采集,一条实用的检测思路:

检测任何进程创建 AF_ALG socket (family=38),特别关注:非 root 用户 + AF_ALG socket + splice 系统调用的组合。

前提是你得已经有 syscall 级别的监控基础设施。如果连 audit 日志都没开,AI 也巧妇难为无米之炊。

❹ 最值得关注的空白:Page Cache 完整性监控

前文分析过,当前 Linux 生态对 page cache 级别的篡改基本是盲的。这恰恰是 AI 可以介入的空白领域。

核心思路:定期对高价值二进制(setuid、关键 daemon)做磁盘内容与内存映像的对比。从 /proc/<pid>/map_files/ 读取内存映像,与磁盘文件做 diff。正常情况下两者应该一致(relocation 除外),任何不一致都是高度可疑的信号。

难点不在算法,而在运营:

  • 监控哪些文件? AI 可以根据权限属性、调用频率、攻击价值自动排优先级

  • 如何区分”正常的 CoW/mmap 差异”和”恶意篡改”? 需要对 ELF 结构和内存映射有理解,AI 可以辅助判断

  • 如何在不影响性能的前提下采样? AI 可以做自适应频率调整

这不是一个成熟的产品方向,但如果有人做出来,对 Copy Fail 这类漏洞的检测价值极大。

| 场景 | AI 能做什么 | 成熟度 | | — | — | — | | 漏洞发现 | 跨模块 dataflow 变体分析 | 可落地 | | 应急响应 | CVE → 资产查询 → 缓解脚本自动化 | 可落地 | | 运行时检测 | syscall 序列异常建模 | 需要基础设施 | | Page cache 监控 | 磁盘/内存一致性对比 + 智能采样 | 研究阶段 | | 攻击面收敛 | 自动生成 seccomp / AppArmor profile | 可落地需验证 |

那么再来看看局限性,有哪些 AI 在安全运营中做不到的事:

  • 不能替代补丁管理:AI 再怎么帮你检测,最终解决问题的还是打补丁和重启。

  • 不能发现零日的在野利用: Copy Fail 在 2017–2026 年间潜伏了 9 年,没有任何 AI 系统在漏洞公开前检测到它的利用。行为检测只能在你知道”要找什么”之后才有效。

  • 不能替代内核级别的架构修复: page 来源追踪这种根本性问题需要内核社区的架构决策,AI 提供不了。

❻ 如果只做一件事

把 AI 用在暴露面评估的自动化上。这是投入最小、见效最快的方向。从 CVE 通告到全量资产受影响清单的时间,从小时级压缩到分钟级。在 Copy Fail 这种 PoC 已公开、补丁未就绪的窗口期里,速度就是一切。

十、写在最后

Copy Fail 大概是近年来最“干净”的 Linux 本地提权漏洞。

不需要竞争条件,不需要特定版本,不需要编译任何东西。一个 10 行的 Python 脚本,跑一次就能拿到 root。在 Dirty Cow 和 Dirty Pipe 之后,Copy Fail 把利用门槛又拉低了一个量级。

更让人不安的是它的隐蔽性。修改只存在于内存中的 page cache,磁盘上的文件完好无损。你的 HIDS 看到的是一个”正常”的 /usr/bin/su,但内核实际执行的是被注入了 shellcode 的版本。除非你专门去对比内存映像和磁盘文件,否则根本不知道发生了什么

这个漏洞提醒我们 2 件事:

第一,内核暴露给非特权用户的攻击面远比我们想象的大。AF_ALG socket 大多数人可能从来没听说过,但它默认就在那里,默认就可用。

第二,多个”合理”的设计决策叠加在一起,可以产生灾难性的后果。AF_ALG 暴露给用户态是合理的,splice 的零拷贝是合理的,authencesn 的 ESN 处理也有其上下文。但这三者的交集就是一个通杀的本地提权。这类漏洞很难通过代码审查发现,因为每一段代码单独看都没有问题。

所以…

别等了。先禁模块,再等补丁,然后重启。 这不是那种可以排到下个维护窗口的事。


参考资料:

  • NVD: nvd.nist.gov/vuln/detail/CVE-2026-31431
  • Theori/Xint 技术分析: xint.io/blog/copy-fail-linux-distributions
  • PoC 仓库: github.com/theori-io/copy-fail-CVE-2026-31431
  • 内核补丁: git.kernel.org/stable/c/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
  • Red Hat Advisory: access.redhat.com/security/cve/cve-2026-31431
  • 漏洞官方页面: copy.fail

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:爆肚的杂货铺 b40du b40du《无声处听惊雷 | Copy Fail 漏洞深度拆解》

评论:0   参与:  0