V0IDNETWORK/CVE-2026-46331

GitHub: V0IDNETWORK/CVE-2026-46331

这是一个 Linux 内核 act_pedit 模块 page-cache 污染漏洞(CVE-2026-46331)的概念验证与技术分析项目,演示了通过 COW 范围计算错误实现本地权限提升至 root 的完整利用链。

Stars: 0 | Forks: 0

# CVE-2026-46331 (pedit COW) – Linux net/sched Packet-Editor Page-Cache Poisoning 漏洞 ## 执行摘要 CVE-2026-46331( nicknamed **“pedit COW”**)是流量控制子系统中的一个 Linux 内核本地权限提升缺陷。非特权用户(在非特权 network namespace 中)可以配置 **`act_pedit`** (packet editor) 过滤器,从而触发对 page cache 的*部分写时复制 (COW) 写入*。实际上,内核会将攻击者控制的数据写入文件的内存映像中,**而不将该页标记为私有**,从而破坏该文件的缓存副本。至关重要的是,该漏洞利用仅需要 CAP_NET_ADMIN(可以在 user namespace 中获得),并且不会修改磁盘上的文件。在实践中,一个名为 *packet_edit_meme* 的可用概念验证 (PoC) 于 2026 年 6 月 17 日发布,演示了如何覆盖 setuid 二进制文件(例如 `/bin/su`)的 page-cache 映像以生成 root shell。该漏洞源于 **`tcf_pedit_act()`** 中 COW 范围计算错误,并已在上游修复(2026 年 6 月 4 日),方法是将可写区域检查移至每个 key 的循环内。 - **受影响版本**:带有 `act_pedit` 的 Linux 内核(大约 v5.18 到 7.1-rc6)。未修复的稳定版本(包括许多发行版内核)均受此漏洞影响。 - **影响**:通过破坏 page cache (page-cache poisoning) 实现本地权限提升至 root。CVSS v3.1:6.0(中危,AV:L/AC:L/PR:H/UI:N/C:N/I:H/A:H)。 - **漏洞利用**:该 PoC 利用非特权用户的 user+network namespace 获取 CAP_NET_ADMIN,设置 `tc` pedit 过滤器,并用 shellcode 覆盖内存中 setuid 二进制文件的 ELF entry point。 - **缓解措施**:更新内核(上游补丁已将 `skb_ensure_writable()` 移至 key 循环内部)。作为变通方法,可以阻止或卸载 `act_pedit` 模块,或者禁用非特权 user namespace(例如 `sysctl user.max_user_namespaces=0`)。采取缓解措施后,执行 drop caches (`echo 3 > /proc/sys/vm/drop_caches`) 以驱逐任何受污染的页。 本报告提供了 CVE-2026-46331 的详细技术分析:其原因、利用、检测和修复策略,并附有供应商公告、CVE 和公开漏洞利用的参考链接。 ## 漏洞概述 **定义:** CVE-2026-46331 是 Linux 内核 *Traffic Control* (`net/sched`) 子系统中的一个越界写入漏洞,具体位于 **`act_pedit`** (packet editor) action 中。函数 **`tcf_pedit_act()`** 在遍历带类型的 key 之前,*过早地*使用静态提示 `tcfp_off_max_hint` 为数据包编辑操作计算“写时复制”范围。然而,某些 key(例如 TCP/UDP header 编辑)仅在运行时才确定其最终字节偏移量。代码从未重新检查这些动态偏移量的可写性。结果,写入操作可能会发生在预先进行 COW 的区域之外:*部分数据包写入内容从未被设为私有*,导致了*部分 COW*。这种错误写入会传播到文件的共享 page-cache 内存中(如果数据包缓冲区恰好引用了文件页),从而破坏缓存的文件映像。 **背景:** Linux 的 **packet editor (`pedit`)** action 允许管理员在数据包遍历配置好的 *tc* 过滤器时,重写数据包 header(链路层、网络层或传输层)内的任意字节。它的工作原理是指定一个偏移量(可能锚定到某个 header)以及一个 32 位的值/掩码。在内部,`pedit` 作用于 socket-buffer (`sk_buff`),并且在修改之前必须使目标数据包内存变为可写状态(通过 COW 方式的 `skb_ensure_writable()`)。理想情况下,内核应该在写入之前克隆(私有拷贝)任何共享页,以避免更改在别处使用的内存。 **根本原因:** 在 `tcf_pedit_act()` 中,代码错误地仅在前期使用 `tcfp_off_max_hint`(最大静态偏移量)计算一次可写范围。此提示不包括在处理数据包时带类型的 key 添加的任何 *runtime header offset*。像 TCP 或 UDP 这样的 key 可以在运行时根据 IP header 的位置计算偏移量(例如,如果前一个 key 移动了网络层 header)。因此,在循环处理每个 key 时,key 的实际偏移量可能会超过预先分配为可写的范围。随后,代码通过 `skb_store_bits()` 写入数据包内存,但由于预先进行 COW 的区域之外的页未被设为私有,该写入破坏了仍与 page cache 共享的页。简而言之,**“过早计算可写数据包范围”**导致了越界的、跨页的写入。负偏移量(例如在 ingress 上编辑 Ethernet header)也被处理不当,甚至 `offset_valid()` 也缺乏对 `INT_MIN` 的检查,加剧了这一缺陷。 **产生原因:** 这个漏洞本质上是写时复制范围计算中的一个逻辑错误。内核假设*静态的*最大偏移量(在加载时已知)足以应对所有的编辑操作。它未能考虑到,在实际应用具有动态偏移量的 key 时,需要更新 COW 范围。在经过一系列排队的编辑操作后,最终的写入可能会落在预先检查的区域之外。由于数据包缓冲区可能引用了内存映射的文件页(例如通过零拷贝机制),这种“部分 COW”写入可能会到达磁盘上文件的 page cache。在实践中,packet editor action 可能会接收到来自 sendfile 或 splice 的页;因此,单个数据包过滤操作可能会间接地将攻击者选择的数据写入文件的内存映像中,而不改变磁盘。 ## 技术分析 **组件和数据流:** 存在漏洞的代码位于 Linux 的 **net/sched** 子系统 (`act_pedit.c`) 中。当数据包匹配配置的 `pedit` 规则时,会调用 `tcf_pedit_act()`。在内部,它确切地调用一次 `skb_ensure_writable(skb, X)`,其中 `X = tcfp_off_max_hint`。这使得数据包的前 `X` 个字节变为私有(COW)。然后,在遍历每个 *key*(编辑操作)的循环中,它通过将 *runtime header offset* 与 key 指定的偏移量相加来计算该 key 的实际写入偏移量,并将一个 32 位的值写入数据包。伪代码如下: ``` u32 off_max = action->tcfp_off_max_hint; skb_ensure_writable(skb, off_max); for (i = 0; i < num_keys; i++) { u32 hdr_off = compute_header_offset(skb, key[i].hdr_type); u32 write_off = hdr_off + key[i].offset; skb_store_bits(skb, write_off, &key[i].value, 4); } ``` 因为 `hdr_off` 仅在处理每个 key 时才进行计算,所以最初的 `skb_ensure_writable()` 调用并没有将其考虑在内。如果 `hdr_off + key[i].offset` 超过了 `off_max`,代码就会回退到在分片(而不是主线性区域)上执行 `skb_store_bits()`,这意味着它会写入一个未设为私有的页。这就是失效点。 **攻击面:** 唯一需要的接口是带有 `pedit` action 的 **tc filter**,这通常需要 **CAP_NET_ADMIN** capability。然而,普通用户可以在私有的 network namespace 中(通过克隆 user namespace)获得 CAP_NET_ADMIN,而不需要实际的特权。因此,非特权用户可以进入 user+net namespace,并在 loopback 上创建 `tc pedit` 规则。写入发生在处理数据包时(攻击者通常在 loopback 上生成流量来触发它)。信任边界(用户与内核之间)被打破,因为内核信任了它自己的 COW 设置,而用户提供的偏移量打破了这个假设。 **内部机制:** 在内核层面,该漏洞表现为**越界写入** (CWE-787)。它破坏了映射到用户空间的内核内存(文件 page cache)。具体来说,它可以覆盖碰巧映射到 socket buffer 中的任何文件页的内容。在概念验证中,`/bin/su` 通过被发送到 socket buffer 中而被 mmap,因此漏洞利用改变了其在内存中的 entry point 字节。这不会修改磁盘上的文件,但任何随后执行该二进制文件的操作都会从缓存中读取受污染的映像。博客分析指出: **信任边界:** 内核错误地假设 `skb_ensure_writable()`(快速路径 COW)能保证所有后续写入的安全。它没有针对每个 key 重新进行检查。用户仅控制数据包过滤器的配置和数据包内容;内核授予了这些权限(通过 network namespace)。一旦这种信任被打破,写入就会逃逸到本应受保护的、由文件支持的内存中。 ## 根本原因分析 根本原因是 **pedit action 中不正确的 COW 范围计算**。在代码层面上,仅使用基于 `tcfp_off_max_hint` 的长度调用了一次 `skb_ensure_writable()`,然后在实际偏移量可能超过此长度的循环内部。一个小的补丁(2026 年 5 月)通过将 `skb_ensure_writable()` 移到循环*内部*(在已知真实偏移量之后),并添加了对负偏移量的检查和特殊处理来修复此问题。换句话说: - **存在缺陷的代码:** skb_ensure_writable(skb, action->tcfp_off_max_hint); for each key: // compute offset (hdr_off + key_offset) skb_store_bits(skb, write_off, ...); - **修复后的代码:** for each key: // compute offset (hdr_off + key_offset) skb_ensure_writable(skb, write_off + 3); skb_store_bits(skb, write_off, ...); 此外,该修复确保对于负偏移量(Ethernet header 编辑)在 headroom 上使用 `skb_cow()`,并防范了 `INT_MIN` 的情况。提交信息(stack.watch 摘要)指出:*“通过将 skb_ensure_writable() 移至已知实际写入偏移量的每个 key 的循环内部进行修复,并添加对偏移量算术运算的溢出检查。”* 因此,**漏洞存在的原因**:在代码审查或设计期间,忽略了针对每个 key 的重新计算。静态提示优化绕过了针对每个 key 重新评估的需要。这似乎是一个诚实失误造成的 bug,而不是恶意的疏忽,但其后果是严重的,因为它违反了 COW 的假设。正如 TuxCare 所指出的,这个 bug 是在常规的“数据损坏”修复的幌子下合并的,当时并没有立即的安全上下文。 ## 发现过程 该漏洞是由内核 commit **8b796475fd78**(2022 年 5 月)引入的,直到 2026 年初才被注意到。根据消息来源,修复(2026 年 5 月 31 日的 commit **899ee91156e5**)是作为普通的数据损坏补丁提交到 netdev 邮件列表的。内核维护者于 2026 年 6 月 4 日合并了该修复 (net-7.1-rc7)。直到 2026 年 6 月 16 日才正式分配了 CVE-2026-46331(大约在补丁出现两周后)。2026 年 6 月 17 日,出现了完全武器化的公开漏洞利用(*packet_edit_meme* PoC)。 在实践中,整个时间顺序如下: - **修复提交(邮件列表):** 2026 年 5 月 17 日(Zhang Cen 的补丁) - **在上游合并修复:** 2026 年 6 月 4 日 (net-7.1-rc7) - **分配 CVE:** 2026 年 6 月 16 日(CNA 录入 CVE-2026-46331) - **公开 PoC:** 2026 年 6 月 17 日 (packet_edit_meme) - **补丁推出:** 2026 年 6 月下旬在大多数发行版中(Red Hat、Debian、Ubuntu 等) 多方通过公开的补丁注意到了这个 bug。例如,Massimiliano Oldani(网络安全研究员)不久后发布了详细的分析文章和漏洞利用,指出*“在分配 CVE 后的 24 小时内,一个公开且有效的概念验证漏洞利用 packet_edit_meme 就出现在了 GitHub 上。”* 一旦 PoC 公开并分配了 CVE,CloudLinux、TuxCare 和 SentinelOne 就发布了分析报告。Debian 安全追踪器和 PT DBugs 也总结了该问题和可用的公告(参见参考资料)。 ## 攻击场景 现实的攻击需要的先决条件极少: - **攻击者能力:** 目标机器上的本地非特权用户。用户必须能够创建带有 network namespace 的新 user namespace(通过 `unshare(CLONE_NEWUSER|CLONE_NEWNET)`),这会在该 namespace 内授予 CAP_NET_ADMIN,而不需要真正的 root 权限。非特权 user namespace 在许多内核(例如 RHEL、Debian)上默认是启用的,并且可以在 Ubuntu 上通过 `aa-exec` 变通方法重新启用。 - **目标条件:** 目标必须运行存在漏洞的 Linux 内核(大约 518–7.1-rc6),并且 `act_pedit` 模块可用。如果 `act_pedit` 是内置的或已经加载,则可以立即利用。如果它是一个模块,它会在配置 `tc pedit` 规则时自动加载。目标不应已应用上游补丁。值得注意的是,攻击者*不需要*拥有对任何文件的写入权限;该漏洞利用是通过数据包过滤器进行写入来工作的。 - **攻击链:** 1. **获取 CAP_NET_ADMIN:** 攻击者运行类似 `unshare --map-root-user --net --pid bash` 的命令,以创建一个新的 user+net namespace。这将在该 namespace 中授予 CAP_NET_ADMIN(用户在内部被映射为 root)。 2. **设置网络:** 攻击者启动 loopback 接口(`ifconfig lo up`),并可选择生成一个监听器(例如 `nc -l 127.0.0.1 9999`)。这提供了用于 TC action 的数据包流。 3. **配置 TC pedit action:** 使用 `tc` 命令或 netlink,攻击者在 `lo` 上创建一个 qdisc 和过滤器,匹配所有数据包(例如 `match u32 0 0`),并附带一个具有特殊构造 key 的 `pedit` action。每个 key 都有一个动态的 header 类型(例如用于 L4 偏移量的 IP header)和一个经过选择的偏移量,使得实际写入位置(header 起点 + 偏移量)刚好位于 `skb_ensure_writable()` 覆盖的范围之外。 4. **生成流量:** 攻击者发送数据(例如通过 `echo '' > /dev/udp/127.0.0.1/53`)来触发过滤器。内核调用 `tcf_pedit_act()`,分配一个 COW 范围,然后遍历各个 key。至少有一个 key 的写入落在预先进行 COW 的区域之外,导致写入进入共享的 pagecache。 5. **Page-cache poisoning:** 与此同时,攻击者已经在 socket 中打开了目标文件(通常是 setuid 二进制文件)。例如,发布的 PoC 通过 `sendfile` 或类似方法将 `/bin/su` mmap 到 socket 中,因此数据包缓冲区引用了该文件的页。然后,越界写入破坏了 `/bin/su` 的内存中副本(特别是 ELF entry point)。 6. **权限提升:** 在漏洞利用写入其 payload 后,攻击者(或原始 namespace 中的父进程)执行受污染的二进制文件(`/bin/su`)。由于内核无意中注入了执行 `setgid(0); setuid(0); execve("/bin/sh")` 的 shellcode,运行 `su` 会弹出一个 root shell。磁盘上的文件从未被更改,因此任何磁盘上的文件完整性工具都不会显示更改。 **影响:** 如果成功,攻击者将在本地获得完全的 root 权限。该漏洞利用可以在一个命令中完成,并且是确定性的。此外,如果使用方式不同,破坏任意由文件支持的页可能会导致拒绝服务(系统崩溃)。发布的 PoC 特别用 shellcode 覆盖了 `/bin/su` 的 entrypoint,但攻击者可以映射的任何文件都可能成为目标。该攻击链不需要特殊的时机或竞争条件,并已在许多发行版(RHEL、Ubuntu、Debian 等)上得到验证。 ## 概念验证 一个名为 *packet_edit_meme* 的公开漏洞利用程序可在 GitHub (sgkdev/packet_edit_meme) 上找到,针对的是 `/bin/su`。我们在不包含破坏性 payload 的情况下描述其基本逻辑: ``` /* Pseudocode outline of the exploit (simplified) */ int main() { /* 1. Identify a setuid binary (su) and its ELF entry offset */ int fd = open("/bin/su", O_RDONLY); long entry = elf_entry_offset(fd); if (entry < 0) abort(); printf("Target %s (UID=%d), entry offset 0x%lx\n", "/bin/su", getuid(), entry); /* 2. Unshare user+net namespace to get CAP_NET_ADMIN locally */ if (unshare(CLONE_NEWUSER | CLONE_NEWNET) < 0) abort(); /* Map UID/GID to root (handled via /proc/self/uid_map, /gid_map) */ // (omit details: write "0 1" to /proc/self/uid_map and gid_map, and deny setgroups) /* 3. Setup environment: bring up loopback and listener */ if (system("ip link set lo up") < 0) abort(); if (system("nc -l 127.0.0.1 9999 &") < 0) abort(); /* 4. Configure a tc pedit action via netlink (simplified) */ // Assume 'pedit_write' sends a packet-edit command to the kernel. // The key offsets below are chosen such that they exceed the initial COW range. char shellcode[/*size=48*/] = { // (assembly for setgid(0); setuid(0); execve("/bin/sh").., padded to 36 or 48 bytes) }; size_t total = sizeof(shellcode), sent = 0; while (sent < total) { int chunk = min(PEDIT_MAX_WRITE, total - sent); /* Issue TC pedit action to write next chunk */ if (pedit_write(fd, entry + sent, &shellcode[sent], chunk) != 0) { fprintf(stderr, "pedit_write failed\n"); exit(1); } sent += chunk; } /* 5. Trigger execution of su (in original namespace) */ execl("/bin/su", "su", NULL); // This will run the poisoned binary as root return 0; } ``` 这个伪代码说明了流程:打开 `/bin/su`,unshare namespaces 以获取 CAP_NET_ADMIN,配置 loopback 和 TC pedit 规则,然后调用函数 `pedit_write(fd, offset, data, len)`(在实际的 PoC 中,这使用了底层的 netlink 调用)来覆盖目标的 page cache。最后,执行该二进制文件,生成一个 root shell。 实际的 PoC 要复杂得多(处理 UID/GID 映射、网络监听和 syscall 级别的 shellcode 字节),但核心概念如上所述。我们强调**不要运行此漏洞利用**,除非是在安全的测试环境中,并且不要针对任何真实系统。以上内容仅供演示。 **注意:** 如果不存在公开且可安全使用的 PoC,我们会明确说明。在这种情况下,PoC 是公开的,我们只是从概念上对其进行描述。为了简短和安全起见,我们省略了原始的 shellcode 字节和实际的 netlink 细节。 ## 漏洞利用流程 1. **Entry Point:** 攻击者必须首先获取 CAP_NET_ADMIN。通常,这意味着从非特权进程中创建一个 user+network namespace(`unshare`),这会授予特定于 namespace 的 CAP_NET_ADMIN。 2. **Initial Access:** 在此 namespace 内,攻击者可以使用常规工具(`ip`、`tc`)配置流量控制。内核的 `act_pedit` 代码路径现在对于数据包来说是可达的。 3. **Trigger:** 攻击者在 loopback 接口上设置一个 `tc filter ... action pedit`。此过滤器匹配数据包(例如 0 匹配),并指定一个或多个带有 header 类型(IP、TCP)和偏移量的**带类型的 key**。选择这些偏移量是为了使得*在内核计算循环内的 header 基址之后*,最终的写入偏移量超过初始的 COW 范围。 4. **Exploitation:** 当处理与过滤器匹配的数据包时,内核会调用 `tcf_pedit_act()`。它执行了一次*不充分的* `skb_ensure_writable()`,然后遍历各个 key。对于至少一个 key,其写入落在一个*没有*被克隆为私有副本的页上。这导致向共享的 page cache 发生**越界写入**。如果 socket buffer 已准备好引用文件的页(通过 sendfile/splice),该写入就会破坏这些文件页。 5. **Post-Exploitation:** 攻击者的 shellcode 已被写入目标二进制文件(例如 `/bin/su`)的 pagecache 中。然后,攻击者(在原始 namespace 中)执行 `/bin/su`。内核读取内存中的映像(带有注入的 payload)并运行 shellcode,从而为攻击者提供 root shell。此时,系统已被完全攻破。 6. **Impact:** 攻击者获得了 root 权限。机密数据可能会被覆盖,但不会直接泄露。完整性被完全破坏(攻击者可以更改任何文件的内存映像)。可用性也可能受到影响(错误写入关键页可能会导致进程或系统崩溃)。CVSS 指标:总体为中危(CVSS 3.1=6.0),但实际影响是严重的本地 root 权限。 此流程以图表形式总结如下: ``` flowchart LR A[Attacker (unprivileged user)] --> B[Unshare into user+net namespace
(gains CAP_NET_ADMIN)] B --> C[Configure TC pedit filter on lo] C --> D{Packet processing by kernel} D --> E[act_pedit computes wrong COW range] E --> F[skb_store_bits writes beyond COW'd region] F --> G[Page cache of target file is corrupted] G --> H[Attacker executes poisoned setuid binary] H --> I[Root shell obtained] ``` ## 入侵指标 - **意外的 page-cache 写入:** 系统文件(尤其是可执行文件)显示出在内存中被更改,而磁盘上没有变化(例如,哈希工具或完整性监视器会在内存中看到不匹配)。 - **模块加载:** 在通常不使用 tc pedit 的系统上,`act_pedit` 模块意外地出现在 `lsmod` 中。(例如,在 Web 服务器上执行 `lsmod | grep act_pedit` 结果非空。) - **`tc` 使用情况:** 来自非特权进程的异常 `tc` 命令或 netlink 消息。审计日志可能会显示向非 root 进程授予了 `CAP_NET_ADMIN`。 - **网络监听:** loopback 端口上的监听器(因为漏洞利用绑定 socket 以强制处理数据包)。例如,`netstat -tulnp` 显示在 127.0.0.1 上有 `nc` 或自定义监听器,这可能是一个迹象。 - **内核日志:** 涉及 `tcf_pedit_act`、`skb_ensure_writable` 的 Oops 或警告,或者 loopback 上流量繁重期间的 soft lockup,或者 tc 处理中的错误。(这些情况通常很不寻常,表明发生了损坏。) - **权限丢弃日志:** Linux 审计日志(`auditd`)显示程序通过 userns 获取 CAP_NET_ADMIN 或写入 `/proc/[pid]/uid_map`。 例如,一个攻击行为指标 (IOA) 是 **page cache 中的文件损坏**:一个排查清单可能包括在繁重的 tc 活动之后验证内存中的文件内容与磁盘上的内容是否一致,特别是对于 setuid 二进制文件。另一个是**创建新 namespace**:监视对 `unshare(CLONE_NEWUSER|CLONE_NEWNET)` 的调用可能会被标记。简而言之,防御者应该关注以下*任何*情况:使用 `act_pedit`、使用 userns 以及 RAM 中可执行文件突然被修改。 ## 检测 要检测漏洞利用尝试: - **SIEM/日志分析:** 对添加 `act_pedit` 过滤器的 `tc` 配置或 netlink 消息发出警报。例如,Sigma 规则可以查找包含 `TCA_ACT_KIND: pedit` 或类似内容的事件。监视审计日志中是否有来自非 root 进程的 `capset CAP_NET_ADMIN`,或者对 `/proc/*/uid_map` 的写入。 - **IDS/IPS:** 不太可能有特定的特征码(本地漏洞利用没有网络特征码),但可以使用启发式方法:loopback 上有意外的 TCP/UDP 数据包流量,同时伴随主机完整性警报。如果可以植入检测工具,则可能检测到特定的数据包编辑。 - **EDR:** 监视读取 `/bin/su`(或其他敏感二进制文件)并在执行此操作的同时突然结合 namespace/unshare syscall 的进程。对任何既打开 setuid 二进制文件又创建 userns 的进程发出警报。 - **WAF/网络设备:** 不适用(本地攻击)。 - **文件完整性监控:** 将关键二进制文件的内存映像与磁盘上的校验和进行比较。如果出现差异(并且没有进行更新),则触发警报。(正如 CloudLinux 所指出的,在发生入侵后 drop caches 只能算是遏制;真正的修复需要重建主机。) - **内核完整性工具:** 使用 Linux Security Modules 或 eBPF 来强制要求只有特定的进程才能附加 TC 过滤器,或者确保 `skb_ensure_writable()` 不会被欺骗(尽管目前没有已知的内置检查)。 总之,防御者应该记录和审计 user namespace 的使用情况、`tc` 命令和模块加载。一种关键方法是:**拒绝或记录任何由不受信任的用户调用 `tc pedit` 的行为**。在受感染的主机上,检查是否已应用 `/etc/modprobe.d/disable-act_pedit.conf`(应该预先应用它)。 ## 缓解措施 **应用补丁:** 主要的修复方式是更新内核。所有主要发行版都在 2026 年 6 月发布了更新。升级到已修复的内核(Linux 7.1.0 或更高版本,或发行版 backport)是最终的解决方案。 **配置更改:** 如果无法立即打补丁,请实施以下缓解措施: - **禁用 `act_pedit`:** 如果您的工作负载不需要 `tc pedit`,请将该模块列入黑名单。例如: echo 'install act_pedit /bin/true' | sudo tee /etc/modprobe.d/disable-act_pedit.conf lsmod | grep -w act_pedit && sudo rmmod act_pedit 这可确保无法加载该 action。(这是由 CloudLinux 和 TuxCare 推荐的。)请勿在合法使用 `tc pedit` 的主机上应用此操作。 - **限制 User Namespace:** 消除非特权 namespace 的攻击向量。在 RHEL/Alma/Debian 上: sudo sysctl -w user.max_user_namespaces=0 echo 'user.max_user_namespaces = 0' | sudo tee /etc/sysctl.d/99-pedit-cow.conf 在 Ubuntu 22.04+ 上: sudo sysctl -w kernel.unprivileged_userns_clone=0 echo 'kernel.unprivileged_userns_clone = 0' | sudo tee /etc/sysctl.d/99-pedit-cow.conf 这可以防止非特权用户创建必要的 user namespace 来获取 CAP_NET_ADMIN。注意:禁用 namespace 可能会破坏无根容器和某些沙盒应用程序。 - **Drop Page Cache(遏制):** 如果您怀疑漏洞利用已经运行,二进制文件的内存中副本可能已被污染。请立即 drop caches 以将其驱逐: sudo sh -c "echo 3 > /proc/sys/vm/drop_caches" 这会强制从磁盘重新加载页。*注意事项:* 如果攻击者已经获得了 root 权限,drop caches 将不会删除他们安装的任何持久化机制。请将此类主机视为已被入侵。 - **最小权限原则:** 审计并限制谁可以使用 `tc`。该漏洞利用只需要 CAP_NET_ADMIN;请确保只有受信任的管理员才具有此 capability。使用 RBAC 或容器化来限制 capability 的授予。 - **网络控制:** 虽然不能直接通过网络进行攻击,但要确保对 loopback 的使用进行了监控。对 `127.0.0.1` 进行防火墙限制是不切实际的,但要确保只有 localhost 流量被用于 TC 操作。 - **供应商公告: 请参阅适用于您的操作系统的官方公告。Red Hat 针对RHEL 8/9/10 发布了 RHSA-2026:27354(及相关公告),Debian 发布了 DSA-6355-1,Ubuntu 的 CVE 页面列出了修复后的内核等。(参见参考资料。) ## 修复方案 长期的修复包括确保所有受影响的系统都使用更新后的内核。应安装包含该修复的内核软件包并重新启动系统。对于无法重新启动的容器或系统,请考虑使用已准备好补丁的 livepatch 解决方案(例如 KernelCare)。 此外,系统设计应假设用户空间可访问的内核接口会随时间而改变。在此 bug 之外,限制 CAP_NET_ADMIN 和过滤 `tc` 使用情况也是良好的做法。 如果发生了入侵,请重建系统。该漏洞*仅会污染 page cache*,但获得 root 权限的攻击者可能已经进行了其他恶意操作;需要进行取证验证。**不要在漏洞利用后依赖文件完整性扫描,**因为如前所述,PoC 会保持磁盘上的文件完整。重新启动和打补丁是安全的修复途径。 ## 影响评估 - **机密性:** *没有直接的数据泄露*,因为此 bug 不会从内核中读取敏感数据。它只是将攻击者的数据写入内存。CVSS v3.1 将机密性影响评定为**无 (C:N)**。 - **完整性:****高 (I:H)**。攻击者可以在未经许可的情况下更改任意由文件支持的页(例如可执行文件、配置文件)的内存中内容。这导致当前运行的系统中这些文件的完整性遭到彻底破坏。 - **可用性:****高 (A:H)**。覆盖内核管理的内存或关键数据结构可能会导致进程或整个系统崩溃。即使未被用于 shellcode,该 bug 也可能被用于破坏关键页并导致拒绝服务。 - **Scope:** 未更改(易受攻击的组件 = 攻击向量 = 受害者范围),因为该漏洞利用是本地的。 考虑到这些因素,典型的 CVSS v3.1 向量是 AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H,得出的**基础分数为 6.0(中危)**。然而需要注意的是,CVSS 并没有体现出该漏洞会授予*提升至 root 的权限*,而这在实践中是至关重要的。(一些来源计算了类似漏洞的 CVSSv4;例如 PT DBugs 在 CVSSv4 上将其列为 8.5。) 其严重性通常被供应商评级为**重要/严重**。Red Hat 针对此 CVE 的公告将其标记为*重要*,而 AWS 将其标记为*中等*(CVSS 6.0)。无论如何,由于获得了 root 权限,在多用户或共享系统上实际的风险是最高的。 ## 相关 CVE 此漏洞属于*page-cache poisoning* 漏洞家族。其他著名的 CVE 包括: - **CVE-2022-0847 (“Dirty Pipe”):** Linux 5.8+ 中的一个类似 LPE bug,其中管道上的 `splice()` 可能会向超出 COW 边界的 page cache 进行写入。它也允许覆盖内存中的文件(不更改磁盘)。 - **CVE-2016-5195 (“Dirty COW”):** `/proc/self/mem` 写时复制中的一个较旧的缺陷,允许对只读映射进行本地写入。 - **CVE-2020-14386 (“Dirty Frag”):** XFRM/ESP 数据包处理(加密)中的一个缺陷,导致在 pagecache 中发生跨页写入。 - **CVE-2023-4099 (“Dirty Clone”):** 另一个与 netfilter 相关的内核 bug。 这些漏洞中的每一个都涉及内核快速路径向其自认为独占的内存进行写入,但实际上并没有独占。CVE-2026-46331 的独特之处在于,它发生在 **net/sched pedit action** 中,并利用 user namespace 绕过权限限制。与 DirtyPipe 或 Dirty COW 不同,它不需要辅助的特权进程(如行为不当的系统程序)——单个非特权用户就可以触发它。 ## 时间线 - **2022-05-10:** Bug 由上游内核中的 commit 8b7964… 引入。 - **2026-05-17:** 补丁提交到 netdev 邮件列表 (Zhang Cen)。 - **2026-05-31:** 上游补丁 (commit 899ee91156e5) 完成。 - **2026-06-04:** 补丁合并到主线 (net-7.1-rc7)。 - **2026-06-16:** 正式分配 CVE-2026-46331。 - **2026-06-17:** 公开 PoC (*packet_edit_meme*) 发布。 - **2026-06-19 至 06-26:** 供应商发布补丁和公告(Red Hat RHSA-2026:27xxx 系列、Debian DSA-6355、Ubuntu USN 等)。宣布了 CloudLinux livepatch 和 KernelCare 更新。 - **06-26 之后:** 新闻、博客、技术分析(TuxCare、SentinelOne 等)以及时间线分析(Oldani 的分析文章)中的报道。 ## 参考资料 - Linux 内核补丁和 NVD 摘要 - Red Hat/CISA/Ubuntu 公告(通过 NVD/OSV) - CloudLinux(CVE-2026-46331 缓解博客) - TuxCare 分析(pedit-COW 博客) - SentinelOne 漏洞数据库条目 - CyberPress 关于 pedit COW 的文章 - Positive Technologies DB (dbugs) 摘要 - Amazon Linux CVE 页面 - Debian 安全追踪器 - CloudLinux 缓解博客(模块黑名单,drop_caches) *所有参考资料均来自可靠的来源(供应商公告、已发布的分析、CVE/NVD 条目)。* ## 关键要点 - **部分 COW 具有危险性:** 始终针对动态偏移量更新 COW 范围。在 `act_pedit` 中,过早计算可写性导致了 page-cache 损坏。 - **User namespace 绕过权限:** 非特权 namespace 允许使用 CAP_NET_ADMIN,使得本地用户能够到达 TC 子系统。禁用 userns 可以缓解许多新出现的内核漏洞利用。 - **Page cache poisoning 影响巨大:** 与基于磁盘的漏洞利用不同,这些攻击不会在磁盘上留下痕迹。文件完整性工具无法检测到它们。 - **纵深防御:** 监控 TC 的使用情况、限制 CAP_NET_ADMIN 以及及时应用内核补丁至关重要。诸如将模块列入黑名单之类的缓解措施可以在全面部署补丁之前争取时间。 - **漏洞生命周期:** 该 CVE 是在修复程序公开*之后*分配的(一个“N-day”漏洞)。这凸显了上游补丁与稳定版发布采用之间的风险差距。组织应该追踪上游的 commit,而不仅仅是 CVE。
标签:CSV导出, Cutter, Linux内核, PoC, Web报告查看器, 安全渗透, 暴力破解, 本地提权, 漏洞分析, 路径探测, 逆向工具