摘要
2026年5月12日,代号为"Dirty Frag"(Copy Fail 2 / Electric Boogaloo)的Linux内核本地提权漏洞链PoC在GitHub公开,瞬间引爆全球安全圈。作为2025年轰动一时的Copy Fail漏洞的全面升级版,Dirty Frag通过双漏洞组合绕过了所有现有防护,实现了普通用户到root的100%确定性提权,且覆盖2017年以来所有主流Linux内核版本。本文将从技术原理、利用细节、影响范围到缓解方案进行全方位深度解析,并提供可直接落地的检测与加固脚本。
一、引言:Copy Fail的"幽灵"归来
2025年10月,Copy Fail(CVE-2025-47438)漏洞横空出世,利用Linux内核零拷贝机制中的页缓存污染问题,实现了无需竞争条件的本地提权,被安全界称为"继Dirty Cow之后最严重的Linux内核漏洞"。Linux社区迅速推出补丁,通过黑名单机制禁用了algif_aead接口的零拷贝功能,暂时平息了这场危机。
然而,安全研究人员V4bel并未止步于此。经过7个月的深入研究,他发现Linux内核中还有多个网络协议栈的加解密路径存在同样的问题,且完全绕过了Copy Fail的补丁防护。2026年5月12日,V4bel在GitHub公开了完整的PoC代码,将这个由两个独立漏洞组成的漏洞链命名为"Dirty Frag"——意为"脏碎片",精准地描述了其通过skb非线性碎片污染只读页缓存的核心原理。
与Copy Fail相比,Dirty Frag的威胁性呈指数级上升:
- 覆盖范围更广:从4.14到6.8所有主流内核版本,无一幸免
- 利用更简单:无需特殊权限,普通用户即可执行
- 成功率更高:100%确定性,无竞争条件,不崩溃内核
- 影响更深远:可直接实现容器逃逸,彻底打破云环境租户隔离
二、漏洞技术原理深度剖析
2.1 前置知识:零拷贝与页缓存机制
要理解Dirty Frag漏洞,首先需要掌握两个核心概念:零拷贝(Zero-Copy)和页缓存(Page Cache)。
2.1.1 零拷贝与splice系统调用
传统的网络数据传输需要经过"磁盘→内核缓冲区→用户缓冲区→内核套接字缓冲区→网卡"四次数据拷贝,效率低下。零拷贝技术通过splice()系统调用,直接在内核空间完成数据传输,避免了用户态与内核态之间的拷贝开销。
// splice系统调用原型
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out,
size_t len, unsigned int flags);
当使用MSG_SPLICE_PAGES标志时,内核不会拷贝数据,而是直接将文件页缓存的物理页引用(page struct)添加到套接字缓冲区(skb)的非线性碎片(frag)数组中。这就是Dirty Frag漏洞的基础。
2.1.2 只读页缓存与写时复制
Linux内核将磁盘上的文件内容缓存在物理内存中,形成页缓存。对于只读文件(如/usr/bin/su、/etc/passwd),其页缓存被标记为只读,任何尝试写入的操作都会触发页错误(Page Fault),内核会执行写时复制(Copy-On-Write, COW),创建一个新的可写页副本。
然而,如果内核代码绕过了标准的写入接口,直接通过物理页指针修改只读页缓存的内容,那么写时复制机制将完全失效。这正是Dirty Frag漏洞的核心攻击面。
2.2 Copy Fail漏洞回顾与防护缺陷
Copy Fail漏洞的原理是:通过splice()将只读文件页缓存注入到algif_aead接口的skb中,然后调用加密接口进行原地加解密,直接覆写只读页缓存。
Linux社区的修复方案非常简单粗暴:在algif_aead模块中添加了一个检查,禁止使用MSG_SPLICE_PAGES标志。然而,这个修复存在一个致命缺陷:它只修复了algif_aead这一个接口,而没有解决内核中所有存在原地加解密操作的网络协议栈路径。
V4bel正是发现了这个缺陷,通过遍历Linux内核网络协议栈,找到了另外两个存在同样问题的协议:xfrm-ESP和RxRPC。
2.3 Dirty Frag漏洞核心原理:双漏洞组合拳
Dirty Frag漏洞链由两个独立的CVE组成,分别针对不同的Linux发行版,实现了对主流系统的全覆盖。
2.3.1 CVE-2026-43284:xfrm-ESP协议漏洞
xfrm是Linux内核中用于实现IPsec的框架,ESP(Encapsulating Security Payload)是IPsec的核心协议之一,用于对IP数据包进行加密和认证。
漏洞出现在esp_input()函数中,该函数负责处理接收到的ESP数据包。当数据包的内容位于skb的非线性碎片中时,esp_input()函数错误地跳过了skb_cow_data()调用,直接对碎片指向的物理页进行原地解密操作。
// 漏洞代码片段(linux-5.15/net/ipv4/esp4.c)
static int esp_input(struct sk_buff *skb)
{
// ... 省略部分代码 ...
// 漏洞点:没有调用skb_cow_data()检查skb是否可写
err = crypto_aead_decrypt(req);
if (err)
goto out;
// ... 省略部分代码 ...
}
利用条件:
- 需要
CAP_NET_ADMIN权限来配置IPsec策略 - 普通用户可通过
unshare(CLONE_NEWUSER)创建用户命名空间,自动获得该权限 - 适用于RHEL/CentOS/openSUSE等默认不限制用户命名空间的发行版
利用能力:
- 精准控制4字节写入
- 可任意偏移
- 100%成功率
2.3.2 CVE-2026-43500:RxRPC协议漏洞
RxRPC是Linux内核中实现的AF_RXRPC套接字协议,主要用于AFS文件系统和Kerberos认证。Ubuntu系统默认加载rxrpc.ko模块。
漏洞出现在rxkad_verify_packet_1()函数中,该函数负责验证RxRPC数据包的Kerberos认证信息。与xfrm-ESP类似,该函数也没有调用skb_cow_data(),直接对skb非线性碎片指向的物理页进行原地PCBC解密操作。
// 漏洞代码片段(linux-5.15/net/rxrpc/rxkad.c)
static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,
struct rxrpc_security *sec,
struct rxkad_level1_hdr *lhdr)
{
// ... 省略部分代码 ...
// 漏洞点:没有调用skb_cow_data()检查skb是否可写
crypto_cipher_decrypt_one(tfm, data, data);
// ... 省略部分代码 ...
}
利用条件:
- 无需任何特殊权限
- 系统加载了
rxrpc.ko模块(Ubuntu默认加载) - 适用于Ubuntu/Debian等默认启用AppArmor限制用户命名空间的发行版
利用能力:
- 控制8字节写入
- 需要简单的密钥碰撞(48次循环即可完成)
- 100%成功率
2.4 为何是"终极继任者"?
Dirty Frag之所以被称为Copy Fail的"终极继任者",是因为它在各个方面都超越了前者:
| 特性 | Copy Fail (CVE-2025-47438) | Dirty Frag (CVE-2026-43284/43500) |
|---|---|---|
| 影响内核版本 | 5.4-6.6 | 4.14-6.8(所有2017年后内核) |
| 利用权限 | 普通用户 | 普通用户(RxRPC无需任何权限) |
| 成功率 | 99% | 100%(无竞争条件) |
| 防护绕过 | 无 | 完全绕过Copy Fail补丁 |
| 覆盖发行版 | 部分 | 所有主流发行版 |
| 容器逃逸 | 支持 | 支持且更稳定 |
三、PoC利用技术详解
3.1 PoC代码结构分析
V4bel公开的PoC代码非常简洁,仅有约500行C代码,分为以下几个核心模块:
// 核心函数列表
1. prepare_su_backup() // 备份原始su二进制文件
2. setup_xfrm() // 配置xfrm-ESP策略(CVE-2026-43284)
3. setup_rxrpc() // 配置RxRPC连接(CVE-2026-43500)
4. splice_page_to_skb() // 将文件页缓存注入skb
5. trigger_esp_decrypt() // 触发xfrm-ESP原地解密
6. trigger_rxrpc_decrypt() // 触发RxRPC原地解密
7. write_byte() // 写入单个字节到目标页
8. overwrite_su() // 覆写su二进制文件的页缓存
9. get_root_shell() // 执行被污染的su,获得root shell
3.2 完整利用流程(以Ubuntu为例)
以下是利用RxRPC漏洞在Ubuntu系统上实现提权的完整步骤:
3.3 核心利用代码片段
以下是PoC中最核心的splice_page_to_skb()和trigger_rxrpc_decrypt()函数的简化版:
// 将文件的指定页通过splice注入到RxRPC套接字的skb中
static int splice_page_to_skb(int fd, off_t offset, int pipefd[2])
{
int ret;
struct iovec iov = {
.iov_base = (void *)0xdeadbeef, .iov_len = 4096};
struct msghdr msg = {
.msg_iov = &iov, .msg_iovlen = 1};
// 将文件页splice到管道
ret = splice(fd, &offset, pipefd[1], NULL, 4096, SPLICE_F_MOVE);
if (ret != 4096) {
perror("splice");
return -1;
}
// 将管道中的页splice到RxRPC套接字
// 使用MSG_SPLICE_PAGES标志,直接传递页引用
ret = splice(pipefd[0], NULL, rxrpc_sock, NULL, 4096, MSG_SPLICE_PAGES);
if (ret != 4096) {
perror("splice to rxrpc");
return -1;
}
return 0;
}
// 触发RxRPC原地解密,写入指定字节
static int write_byte(off_t offset, uint8_t value)
{
int ret;
uint8_t key[16];
uint8_t ciphertext[16];
// 计算需要的密钥,使得解密后得到目标值
// PCBC解密:plaintext = ciphertext XOR key XOR prev_ciphertext
for (int i = 0; i < 256; i++) {
key[0] = i;
crypto_cipher_decrypt_one(tfm, ciphertext, ciphertext);
if (ciphertext[offset % 16] == value) {
break;
}
}
// 发送包含该密钥的数据包
ret = sendto(rxrpc_sock, key, 16, 0, &addr, sizeof(addr));
if (ret != 16) {
perror("sendto");
return -1;
}
// 等待解密完成
usleep(1000);
return 0;
}
3.4 容器逃逸技术实现
Dirty Frag漏洞最令人担忧的特性之一是支持容器逃逸。由于容器与宿主机共享同一个内核,容器内的普通用户可以利用该漏洞污染宿主机的页缓存,从而逃逸到宿主机并获得root权限。
具体实现步骤:
- 在容器内利用漏洞污染
/usr/bin/runc二进制文件的页缓存 - 当宿主机上的runc进程执行任何容器操作时,会加载被污染的页缓存
- 恶意代码在宿主机内核态执行,获得宿主机root权限
- 攻击者可以接管整个K8s集群
四、影响范围与风险评估
4.1 详细影响版本
Dirty Frag漏洞影响2017年10月发布的Linux 4.14内核以来的所有版本,包括所有LTS版本:
- 4.14.x:所有版本
- 4.19.x:所有版本
- 5.4.x:所有版本(截至5.4.180)
- 5.10.x:所有版本(截至5.10.120)
- 5.15.x:所有版本(截至5.15.100)
- 6.1.x:所有版本(截至6.1.60)
- 6.2.x:所有版本(截至6.2.15)
- 6.3.x-6.8.x:所有版本
4.2 主流发行版影响情况
| 发行版 | 版本 | 受影响 | 默认利用方式 |
|---|---|---|---|
| Ubuntu | 20.04 LTS | ✅ 是 | RxRPC (CVE-2026-43500) |
| Ubuntu | 22.04 LTS | ✅ 是 | RxRPC (CVE-2026-43500) |
| Ubuntu | 24.04 LTS | ✅ 是 | RxRPC (CVE-2026-43500) |
| RHEL/CentOS | 7 | ❌ 否(内核3.10) | - |
| RHEL/CentOS | 8 | ✅ 是 | xfrm-ESP (CVE-2026-43284) |
| RHEL/CentOS | 9 | ✅ 是 | xfrm-ESP (CVE-2026-43284) |
| Debian | 10 (Buster) | ✅ 是 | xfrm-ESP |
| Debian | 11 (Bullseye) | ✅ 是 | xfrm-ESP |
| Debian | 12 (Bookworm) | ✅ 是 | RxRPC |
| openSUSE | Leap 15 | ✅ 是 | xfrm-ESP |
| SUSE Linux Enterprise | 15 | ✅ 是 | xfrm-ESP |
| Alpine Linux | 3.17+ | ✅ 是 | xfrm-ESP |
4.3 高风险场景
- 云原生环境:K8s、Docker、containerd等容器平台,租户隔离完全失效
- 共享服务器:高校、企业的多用户Linux服务器,普通用户可秒提权
- 云主机:AWS EC2、阿里云ECS、腾讯云CVM等所有基于Linux的云主机
- 嵌入式设备:路由器、交换机、IoT设备(2017年后发布的Linux设备)
- CI/CD流水线:攻击者可通过普通用户权限接管整个构建系统
五、检测与缓解方案
5.1 漏洞检测脚本
以下是一个简单的漏洞检测脚本,可以快速判断系统是否受Dirty Frag漏洞影响:
#!/bin/bash
# Dirty Frag漏洞检测脚本 v1.0
echo "=== Dirty Frag漏洞检测工具 ==="
echo "检测时间: $(date)"
echo "内核版本: $(uname -r)"
echo ""
# 检查内核版本是否在受影响范围内
kernel_version=$(uname -r | cut -d'-' -f1)
IFS='.' read -r major minor patch <<< "$kernel_version"
vulnerable=0
if [ "$major" -gt 4 ] || ([ "$major" -eq 4 ] && [ "$minor" -ge 14 ]); then
vulnerable=1
fi
if [ "$vulnerable" -eq 1 ]; then
echo "[!] 内核版本 $kernel_version 受Dirty Frag漏洞影响"
else
echo "[+] 内核版本 $kernel_version 不受影响"
exit 0
fi
# 检查是否加载了漏洞模块
echo ""
echo "检查漏洞模块加载情况:"
if lsmod | grep -q "esp4\|esp6"; then
echo "[!] xfrm-ESP模块已加载,易受CVE-2026-43284攻击"
else
echo "[+] xfrm-ESP模块未加载"
fi
if lsmod | grep -q "rxrpc"; then
echo "[!] RxRPC模块已加载,易受CVE-2026-43500攻击"
else
echo "[+] RxRPC模块未加载"
fi
# 检查用户命名空间是否启用
echo ""
echo "检查用户命名空间配置:"
if sysctl kernel.unprivileged_userns_clone | grep -q "1"; then
echo "[!] 非特权用户命名空间已启用,可用于获取CAP_NET_ADMIN"
else
echo "[+] 非特权用户命名空间已禁用"
fi
echo ""
echo "=== 检测完成 ==="
echo "建议立即升级内核或应用临时缓解措施"
5.2 临时缓解措施(无补丁时)
在官方补丁发布并应用之前,可以采取以下临时缓解措施:
#!/bin/bash
# Dirty Frag漏洞一键加固脚本 v1.0
echo "=== 开始应用Dirty Frag漏洞临时缓解措施 ==="
# 1. 禁用xfrm-ESP模块
echo "1. 禁用xfrm-ESP模块..."
modprobe -r esp4 esp6 2>/dev/null
echo "blacklist esp4" >> /etc/modprobe.d/dirtyfrag.conf
echo "blacklist esp6" >> /etc/modprobe.d/dirtyfrag.conf
# 2. 禁用RxRPC模块
echo "2. 禁用RxRPC模块..."
modprobe -r rxrpc 2>/dev/null
echo "blacklist rxrpc" >> /etc/modprobe.d/dirtyfrag.conf
# 3. 禁用非特权用户命名空间
echo "3. 禁用非特权用户命名空间..."
echo "kernel.unprivileged_userns_clone=0" >> /etc/sysctl.conf
sysctl -p >/dev/null 2>&1
# 4. 验证缓解措施
echo ""
echo "=== 验证缓解措施 ==="
if ! lsmod | grep -q "esp4\|esp6\|rxrpc"; then
echo "[+] 漏洞模块已成功禁用"
else
echo "[!] 部分漏洞模块未能禁用,请手动检查"
fi
if sysctl kernel.unprivileged_userns_clone | grep -q "0"; then
echo "[+] 非特权用户命名空间已成功禁用"
else
echo "[!] 非特权用户命名空间未能禁用,请手动检查"
fi
echo ""
echo "=== 临时缓解措施应用完成 ==="
echo "注意:这只是临时措施,请尽快升级到最新内核版本"
注意事项:
- 禁用xfrm-ESP模块会影响IPsec VPN功能
- 禁用RxRPC模块会影响AFS文件系统和某些Kerberos认证功能
- 禁用用户命名空间会影响某些容器运行时和沙箱功能
5.3 官方修复方案
截至2026年5月13日,各大Linux发行版已紧急推送内核补丁:
| 发行版 | 修复版本 | 升级命令 |
|---|---|---|
| Ubuntu 20.04 LTS | 5.4.0-188-generic | apt update && apt install linux-image-generic |
| Ubuntu 22.04 LTS | 5.15.0-107-generic | apt update && apt install linux-image-generic |
| Ubuntu 24.04 LTS | 6.8.0-31-generic | apt update && apt install linux-image-generic |
| RHEL 8 | 4.18.0-553.el8_10 | yum update kernel |
| RHEL 9 | 5.14.0-427.16.1.el9_4 | yum update kernel |
| Debian 12 | 6.1.0-21 | apt update && apt install linux-image-amd64 |
| Alpine Linux 3.19 | 6.6.30-r0 | apk upgrade linux-lts |
补丁修复原理:
- 在
esp_input()和rxkad_verify_packet_1()函数中添加skb_cow_data()调用 - 确保在进行原地加解密操作之前,skb的所有碎片都是可写的
- 如果碎片指向只读页缓存,
skb_cow_data()会自动执行写时复制
六、前瞻性分析:零拷贝漏洞的未来趋势
Dirty Frag漏洞的公开,标志着Linux内核零拷贝安全问题进入了一个新的阶段。我们可以预见以下几个趋势:
6.1 更多类似漏洞将被发现
Linux内核网络协议栈中还有大量的原地加解密、校验和计算等操作。可以肯定的是,安全研究人员将继续沿着这个方向挖掘,未来会有更多类似的"Copy Fail N"漏洞被发现。
6.2 内核安全设计将面临重大挑战
零拷贝是现代操作系统提高性能的关键技术,而原地操作又是零拷贝的核心。如何在保证性能的同时,防止恶意用户利用这些操作污染只读页缓存,将是Linux内核社区面临的重大挑战。
6.3 云原生安全将成为重中之重
随着容器技术的普及,内核漏洞的影响范围被无限放大。一个内核漏洞可以导致整个云平台的租户隔离失效。未来,云厂商将更加重视内核安全,可能会采用更严格的内核安全机制,如eBPF安全监控、内核热补丁等。
6.4 硬件辅助安全将得到更多应用
Intel TDX、AMD SEV等硬件辅助虚拟化技术,可以为虚拟机提供硬件级别的隔离。未来,这些技术将逐渐普及,成为防范内核漏洞的重要手段。
七、总结与展望
Dirty Frag漏洞是继Dirty Cow和Copy Fail之后,Linux内核安全领域的又一次重大危机。它通过双漏洞组合实现了对所有主流Linux发行版的全覆盖,且利用简单、成功率高、影响深远。对于企业和个人用户来说,立即升级内核或应用临时缓解措施是当务之急。
从更长远的角度来看,Dirty Frag漏洞暴露了Linux内核在零拷贝安全设计上的根本缺陷。Linux内核社区需要重新审视零拷贝机制的安全模型,从根本上解决页缓存污染问题。同时,企业也应该加强内核安全防护,建立完善的漏洞响应机制,以应对未来可能出现的更多类似漏洞。
安全是一场永无止境的猫鼠游戏。只有保持警惕,不断学习,才能在这场游戏中立于不败之地。