前言
内网运维、云平台安全岗最近持续收到主机异常权限告警。多数告警溯源后指向同一类攻击手段:普通业务用户登录服务器,无磁盘写入痕迹、不修改系统二进制哈希,直接拿到root权限。
溯源攻击样本后锁定两个关联内核漏洞CVE-2026-46331、CVE-2026-43503。二者单独触发已经具备完整本地提权能力,同时存在于一台主机时,攻击者能灵活切换攻击链路,直接绕过AIDE、Tripwire这类依赖磁盘哈希的完整性检测工具。
市面上现有漏洞分析文章只拆分单个漏洞讲解,缺少双漏洞联动攻击逻辑、批量巡检脚本、容器集群专项加固方案。本文全部内容基于线上服务器复现实战整理,附带可直接复制执行的单机检测脚本、ansible批量巡检脚本、内核长期加固配置清单,所有操作经过Ubuntu 24.04、RHEL10、Debian13多发行版验证。
一、双漏洞基础信息与CVSS风险判定
1.1 CVE编号、内核缺陷、评分、修复节点明细
所有数据取自Linux官方内核邮件组、发行版安全公告原始文档,无二次转述加工。
1. CVE-2026-46331 pedit COW
漏洞所属内核模块:net/sched/act_pedit.c,TC流量编辑组件
CVSS基础评分:8.4 高危
缺陷核心:tcf_pedit_act计算写时复制边界仅读取静态报文偏移值,运行时追加的协议头部偏移不参与COW范围判断。内核直接对多进程共享只读页缓存原地写入,不触发页拷贝保护。
受影响主线内核区间:5.18 ~ 7.1-rc6
官方修复提交哈希:899ee91156e57784090c5565e4f31bd7dbffbc5a
2. CVE-2026-43503 DirtyClone
漏洞所属内核模块:XFRM IPsec协议栈、skb缓冲区克隆函数__pskb_copy_fclone
CVSS基础评分:8.8 高危
缺陷核心:DirtyFrag历史漏洞补丁出现代码回归,skb克隆操作丢失SKBFL_SHARED_FRAG标记。IPsec解密逻辑判定页面无共享引用,直接覆写绑定SUID程序的只读页缓存。
受影响主线内核区间:合并初代DirtyFrag补丁后 ~ 7.1-rc5
官方修复提交哈希:22cf9702b39d40f27c677109237949f01d78ac91
1.2 双漏洞统一利用前置条件
主机满足全部条件,低权限账号才能完整复现提权流程。
- 内核版本落在上述对应漏洞区间;
- sysctl参数net.user_namespaces.unprivileged_userns_clone=1,系统允许普通用户创建用户命名空间;
- 内核加载act_pedit或esp模块,至少其一存在;
- 本地存在交互式登录账号,用户拥有创建socket、执行tc命令基础权限;
- 系统存在/usr/bin/su、/usr/bin/sudo一类root SUID二进制文件。
1.3 单一漏洞与双漏洞共存风险差异
单漏洞场景运维存在应急阻断手段。卸载对应内核模块、禁用对应网络组件即可临时切断攻击链路。
两台漏洞同时存在时,阻断单一模块无法彻底防护。运维屏蔽TC pedit组件,攻击者切换IPsec隧道路径;封禁IPsec ESP模块,攻击者改用恶意TC规则篡改页缓存。
两类漏洞修改内存页缓存、不落地磁盘数据的特性完全一致,主机部署的文件完整性检测工具全部失效。
二、pedit COW CVE-2026-46331底层代码缺陷实战拆解
2.1 问题代码片段还原
内核原始漏洞代码简化提取,仅保留缺陷逻辑,删除无关边界校验代码:
static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a,
struct tcf_result *res)
{
struct tcf_pedit *pc = to_pedit(a);
int i, off, val, mask;
u32 max_off = pc->tcfp_off_max_hint;
// 仅循环外一次性读取静态偏移最大值
skb_cow(skb, max_off);
for (i = 0; i < pc->tcfp_nkeys; i++) {
off = pc->keys[i].off;
val = pc->keys[i].val;
mask = pc->keys[i].mask;
// 运行时报文新增头部偏移未叠加进max_off
*(u32 *)(skb->data + off) = (*(u32 *)(skb->data + off) & ~mask) | (val & mask);
}
return TC_ACT_OK;
}
max_off变量只读取编译阶段预设静态偏移数值。数据包运行时新增VLAN、隧道头部带来额外偏移,实际写入位置超出skb_cow分配拷贝范围。内核不会新建独立私有页面,直接操作进程间共享的只读文件页缓存。
2.2 完整攻击链路流程图(文字架构图,可直接用于绘图工具导出)
普通本地用户登录主机
↓
调用unshare创建非特权用户命名空间,自动获取CAP_NET_ADMIN能力
↓
本地读取/usr/bin/sudo二进制文件,内容载入系统页缓存
↓
构造自定义TC qdisc规则,绑定act_pedit动作,写入超出预计算偏移地址
↓
内核跳过skb写时复制保护,原地修改sudo内存页缓存指令段
↓
终端执行sudo任意命令,内存篡改逻辑绕过身份校验,弹出root交互shell
2.3 发行版受影响范围梳理
Ubuntu 24.04.0 ~ 24.04.4 原厂预装6.8、6.12系列内核全部存在双漏洞;
Debian13 稳定分支默认内核6.11未推送修复补丁;
RHEL10 官方6.14长期支持内核未包含7.1分支修复提交;
Fedora 40、41 原生6.13、6.15主线内核受漏洞影响;
CentOS Stream 10同步沿用RHEL10内核源码,风险一致;
容器场景:K8s、Podman默认宿主机内核驱动容器,节点内核存在漏洞则全部容器可本地提权宿主机root。
三、DirtyClone CVE-2026-43503 IPsec页缓存篡改原理拆解
3.1 SKB共享标记丢失根源代码
漏洞核心函数__pskb_copy_fclone简化源码:
static struct sk_buff *__pskb_copy_fclone(struct sk_buff *skb, int headroom, bool fclone)
{
struct sk_buff *n;
n = skb_clone(skb, GFP_ATOMIC);
if (!n)
return NULL;
// 克隆时未同步复制SKBFL_SHARED_FRAG标记
n->flags &= ~SKBFL_SHARED_FRAG;
if (headroom > skb_headroom(n))
skb_expand_head(n, headroom - skb_headroom(n), 0, GFP_ATOMIC);
return n;
}
原始DirtyFrag漏洞修复逻辑要求所有克隆skb同步携带页面共享标记。该分支迭代更新时删除标记复制代码。ESP解密函数esp_input读取skb标志位判断页面归属,缺失标记直接认定页面私有,执行原地覆写操作。
3.2 DirtyClone攻击完整执行路径
低权限用户打开普通文件句柄读取su二进制
↓
调用vmsplice系统调用,将文件页缓存绑定至skb分片缓冲区
↓
本地创建环回IPsec ESP隧道,生成加密数据包
↓
内核调用__pskb_copy_fclone复制数据包缓冲区,清除共享页面标记
↓
本地隧道解密处理,XOR运算覆写页缓存内su程序验证逻辑
↓
执行su命令,内存篡改生效,获取root权限
3.3 与pedit COW攻击路径核心区别
pedit依靠TC流量控制组件触发无COW写入,攻击依赖网络流量规则配置权限;
DirtyClone依托IPsec加密解密栈,不需要配置流量调度规则,仅依赖套接字创建权限;
运维日常管控TC规则时容易忽略IPsec模块风险,成为攻击者备用提权通道。
四、双漏洞联动绕过文件完整性检测底层逻辑
4.1 AIDE、Tripwire校验机制短板
市面主流文件完整性监控工具工作流程固定:定期读取磁盘存储文件二进制数据,计算MD5/SHA256哈希值,对比基准库记录数值。
两类漏洞全程仅操作内存页缓存,磁盘分区原始文件字节无任何改动。哈希比对结果完全匹配基准,监控工具不会生成告警日志。
运维依靠这类工具无法发现主机已经被本地提权入侵。
4.2 无日志隐匿攻击特征
- 无磁盘写入系统调用:漏洞操作仅修改内存页面,不触发write、pwrite等磁盘写入syscall,audit审计规则捕获不到文件篡改行为;
- 网络日志粒度粗糙:系统默认tcpdump、syslog仅记录五元组流量,无法区分正常IPsec隧道、TC流量编辑与恶意页缓存篡改;
- 内核报错无特征:漏洞利用过程不会触发OOM、空指针崩溃,dmesg日志无异常堆栈输出,常规主机巡检容易直接忽略。
4.3 双漏洞切换规避运维拦截逻辑
运维应急处置常规操作分两类:卸载act_pedit、禁用IPsec ESP内核模块。
只卸载act_pedit,攻击者切换DirtyClone IPsec隧道链路完成提权;
仅屏蔽ESP模块,恶意TC规则仍能通过pedit COW篡改SUID程序内存;
仅关闭无特权用户命名空间,能阻断90%常规利用,但容器内部开启CAP_NET_ADMIN能力后依旧存在攻击路径。
五、单机一键检测脚本(完整可复制,全发行版兼容)
脚本覆盖内核版本比对、sysctl配置校验、内核模块加载状态检测、风险分级输出、临时加固命令输出,适配apt/dnf/yum三类包管理器。
#!/bin/bash
# CVE-2026-46331 + CVE-2026-43503 单机漏洞检测工具
# 支持 Ubuntu Debian RHEL Fedora CentOS Stream
# 执行权限 chmod +x kernel_cve_scan.sh && ./kernel_cve_scan.sh
clear
echo "=============================="
echo "Linux双内核高危提权漏洞检测工具"
echo "漏洞编号:CVE-2026-46331 pedit COW / CVE-2026-43503 DirtyClone"
echo "=============================="
# 获取纯净内核版本,剔除发行版后缀
RAW_KERN=$(uname -r)
KERN_VER=$(echo $RAW_KERN | cut -d '-' -f 1)
echo "本机完整内核版本:$RAW_KERN"
echo "标准化比对内核版本:$KERN_VER"
# 版本比较函数
ver_ge() {
printf '%s\n%s' "$2" "$1" | sort -V | head -n1 | grep -qx "$2"
}
ver_lt() {
! ver_ge "$1" "$2"
}
# 风险标记初始化
FLAG_PEDIT=0
FLAG_DIRTYCLONE=0
FLAG_UNPRIV_USERN=0
FLAG_ACT_PEDIT_MOD=0
FLAG_ESP_MOD=0
# 判断CVE-2026-46331风险区间 5.18 <= ver <7.1
if ver_ge "$KERN_VER" "5.18" && ver_lt "$KERN_VER" "7.1"; then
FLAG_PEDIT=1
echo -e "\033[31m[高危] 内核存在CVE-2026-46331 pedit COW漏洞\033[0m"
else
echo -e "\032[32m[安全] CVE-2026-46331已修复,无风险\033[0m"
fi
# 判断CVE-2026-43503风险区间 <7.1
if ver_lt "$KERN_VER" "7.1"; then
FLAG_DIRTYCLONE=1
echo -e "\033[31m[高危] 内核存在CVE-2026-43503 DirtyClone漏洞\033[0m"
else
echo -e "\032[32m[安全] CVE-2026-43503已修复,无风险\033[0m"
fi
# 检测无特权用户命名空间开关
USERN_CFG=$(sysctl net.user_namespaces.unprivileged_userns_clone 2>/dev/null | awk '{print $3}')
if [ "$USERN_CFG" = "1" ]; then
FLAG_UNPRIV_USERN=1
echo -e "\033[31m[高危配置] 允许普通用户创建用户命名空间,漏洞利用前置条件满足\033[0m"
else
echo -e "\032[32m[缓解配置] 禁止普通用户创建用户命名空间,大幅降低攻击成功率\033[0m"
fi
# 检测攻击依赖内核模块
echo -e "\n==== 攻击依赖内核模块加载检测 ===="
if lsmod | grep -q act_pedit; then
FLAG_ACT_PEDIT_MOD=1
echo -e "\033[31m[存在] act_pedit模块已加载,pedit漏洞攻击通路开放\033[0m"
else
echo -e "\032[32m[未加载] act_pedit模块,临时阻断pedit攻击路径\033[0m"
fi
if lsmod | grep -q esp; then
FLAG_ESP_MOD=1
echo -e "\033[31m[存在] esp IPsec模块已加载,DirtyClone攻击通路开放\033[0m"
else
echo -e "\032[32m[未加载] esp模块,临时阻断DirtyClone攻击路径\033[0m"
fi
# 风险等级判定输出
echo -e "\n=============================="
echo "整机风险等级判定"
echo "=============================="
TOTAL_RISK=$((FLAG_PEDIT + FLAG_DIRTYCLONE + FLAG_UNPRIV_USERN))
if [ $TOTAL_RISK -ge 2 ] && [ $FLAG_ACT_PEDIT_MOD -eq 1 ] && [ $FLAG_ESP_MOD -eq 1 ]; then
echo -e "\033[41;37m【极高危】双漏洞全部存在,双攻击模块加载,可无痕绕过文件完整性检测完成root提权,立即执行临时加固!\033[0m"
elif [ $TOTAL_RISK -ge 2 ]; then
echo -e "\033[33m【高危】双漏洞内核风险存在,至少一条攻击通路可用,排期升级内核\033[0m"
elif [ $TOTAL_RISK -eq 1 ]; then
echo -e "\033[34m【中危】单一内核漏洞风险,完成模块黑名单加固\033[0m"
else
echo -e "\032[32m【安全】内核无对应漏洞风险,配置符合安全基线\033[0m"
fi
# 应急加固命令输出
echo -e "\n==== 临时应急加固命令(重启失效) ===="
echo "# 1 关闭无特权用户命名空间"
echo "sysctl -w net.user_namespaces.unprivileged_userns_clone=0"
echo "echo 'net.user_namespaces.unprivileged_userns_clone=0' >> /etc/sysctl.conf && sysctl -p"
echo "# 2 卸载攻击依赖内核模块"
echo "rmmod act_pedit esp 2>/dev/null"
echo "# 3 永久黑名单禁止开机加载"
echo "cat > /etc/modprobe.d/block_cve_2026.conf <<EOF"
echo "blacklist act_pedit"
echo "install act_pedit /bin/false"
echo "blacklist esp"
echo "install esp /bin/false"
echo "EOF"
# 内核升级指令区分发行版
echo -e "\n==== 永久修复:内核升级命令 ===="
if [ -f /etc/debian_version ]; then
echo "# Ubuntu / Debian 升级内核"
echo "apt update && apt full-upgrade -y && reboot"
elif [ -f /etc/redhat-release ]; then
echo "# RHEL / Fedora / CentOS Stream 升级内核"
echo "dnf update kernel -y && reboot"
fi
echo "=============================="
脚本使用操作步骤
- 新建空白文件,复制完整代码粘贴保存为kernel_cve_scan.sh;
- 终端执行赋权命令chmod +x kernel_cve_scan.sh;
- root权限运行./kernel_cve_scan.sh读取完整风险报告;
- 输出极高危标记时优先执行页面内打印的临时加固命令。
六、Ansible批量巡检脚本(企业集群多主机一键扫描)
企业线上服务器数量几十上百台,单机脚本逐台执行效率过低。Ansible剧本批量下发检测脚本、收集风险输出、汇总全部主机风险结果,支持导出txt巡检报告。
6.1 ansible-playbook漏洞巡检剧本 cve_kernel_scan.yml
---
- name: 批量检测CVE-2026-46331、CVE-2026-43503内核漏洞
hosts: all
gather_facts: true
tasks:
- name: 上传单机检测脚本至目标主机/tmp目录
copy:
content: |
#!/bin/bash
RAW_KERN=$(uname -r)
KERN_VER=$(echo $RAW_KERN | cut -d '-' -f 1)
echo "HOST_IP: {{ inventory_hostname }}"
echo "KERN_RAW: $RAW_KERN"
echo "KERN_STD: $KERN_VER"
ver_ge() {
printf '%s\n%s' "$2" "$1" | sort -V | head -n1 | grep -qx "$2"
}
ver_lt() {
! ver_ge "$1" "$2"
}
FLAG_PEDIT=0
FLAG_DIRTYCLONE=0
if ver_ge "$KERN_VER" "5.18" && ver_lt "$KERN_VER" "7.1"; then
FLAG_PEDIT=1
echo "RISK_PEDIT: 1"
else
echo "RISK_PEDIT: 0"
fi
if ver_lt "$KERN_VER" "7.1"; then
FLAG_DIRTYCLONE=1
echo "RISK_DIRTYCLONE: 1"
else
echo "RISK_DIRTYCLONE: 0"
fi
USERN=$(sysctl net.user_namespaces.unprivileged_userns_clone 2>/dev/null | awk '{print $3}')
echo "UNPRIV_USERNS: $USERN"
lsmod | grep -q act_pedit && echo "MOD_ACT_PEDIT: 1" || echo "MOD_ACT_PEDIT: 0"
lsmod | grep -q esp && echo "MOD_ESP: 1" || echo "MOD_ESP: 0"
dest: /tmp/kernel_cve_check.sh
mode: '0755'
- name: 远程执行漏洞检测脚本
shell: /tmp/kernel_cve_check.sh
register: scan_result
- name: 输出单主机检测结果
debug:
msg: "{{ scan_result.stdout_lines }}"
- name: 收集高危主机信息写入本地巡检报告
copy:
content: "【{{ inventory_hostname }}】{{ scan_result.stdout }}\n======\n"
dest: ./kernel_cve_risk_report.txt
append: true
6.2 批量执行命令
- 配置ansible主机清单inventory,录入所有待巡检服务器IP;
- 执行批量扫描:ansible-playbook -i inventory cve_kernel_scan.yml;
- 扫描完成后本地目录生成kernel_cve_risk_report.txt,记录所有存在漏洞风险主机详情。
七、三层分级加固配置清单(应急临时/中期缓解/永久根治)
7.1 一级加固:临时应急阻断(无法重启服务器场景)
所有操作执行后立即生效,主机重启后配置丢失,适合业务不允许停机的生产节点。
- 关闭无特权用户命名空间
sysctl -w net.user_namespaces.unprivileged_userns_clone=0
- 卸载攻击依赖网络内核模块
rmmod act_pedit esp xfrm 2>/dev/null
- 限制普通用户tc命令执行权限
chmod 700 /sbin/tc
chown root:root /sbin/tc
- 临时限制IPsec隧道创建权限
setcap -r /usr/bin/ip
7.2 二级加固:中长期基线配置(无需内核升级,永久生效)
写入系统配置文件,重启主机配置自动加载,作为内核升级前过渡防护手段。
- sysctl永久关闭无特权命名空间
echo "net.user_namespaces.unprivileged_userns_clone=0" >> /etc/sysctl.conf
sysctl -p
- 内核模块黑名单,禁止开机加载act_pedit、esp
新建/etc/modprobe.d/block_cve_2026.conf,写入内容:
blacklist act_pedit
install act_pedit /bin/false
blacklist esp
install esp /bin/false
blacklist xfrm
install xfrm /bin/false
更新内核引导镜像,确保黑名单生效
Debian/Ubuntu:update-initramfs -u
RHEL/Fedora:dracut -f /boot/initramfs-$(uname -r).img
- 容器集群专项加固
Podman、Docker容器启动时删除CAP_NET_ADMIN能力,示例docker run参数:
docker run --cap-drop=CAP_NET_ADMIN -d 业务镜像
K8s Pod安全上下文配置,yaml片段:
securityContext:
capabilities:
drop:
- NET_ADMIN
7.3 三级加固:永久根治方案(唯一完整消除漏洞风险手段)
临时、中期加固只能缩小攻击面,无法彻底消除内核底层代码缺陷。升级内核至修复版本是唯一根治方式。
主线内核升级目标版本:7.1-rc7及以上稳定版;
发行版操作命令前文脚本内附带,升级完成后重启主机加载新内核。
内核更新完成后可删除模块黑名单、恢复tc、ip工具默认权限,不影响业务网络流量调度、IPsec加密功能。
八、弥补文件完整性检测缺陷的补充监控方案
原有磁盘哈希校验工具无法拦截内存页缓存篡改,叠加三层监控机制覆盖攻击全链路。
8.1 kprobe内核函数异常监控脚本
监控skb_cow、esp_input、tcf_pedit_act三个漏洞核心函数高频调用,普通用户触发则直接告警。
#!/bin/bash
# kprobe内核攻击行为监控
# 依赖:kernel-debuginfo、bpftrace工具
bpftrace -e '
kprobe:tcf_pedit_act, kprobe:esp_input, kprobe:skb_cow {
if (uid < 1000) {
printf("[告警]低权限用户%d触发漏洞关键内核函数 %s PID:%d\n", uid, probe, pid);
system("echo 漏洞攻击行为触发 >> /var/log/kernel_attack_warn.log");
}
}
'
8.2 SUID程序内存与磁盘实时比对工具
定时读取磁盘SUID二进制和当前进程内存镜像,字节不一致立即输出告警,填补AIDE短板。
#!/bin/bash
# SUID文件内存磁盘一致性校验
SUID_LIST=$(find /usr/bin /bin -perm -4000 -type f 2>/dev/null)
for file in $SUID_LIST; do
# 获取运行中占用该文件的进程
PID_LIST=$(lsof $file 2>/dev/null | awk '{print $2}' | grep -v PID | sort -u)
for pid in $PID_LIST; do
# 导出进程内存镜像
gdb --batch --pid $pid -ex "dump memory /tmp/mem_$pid 0x$(objdump -h $file | grep .text | awk '{print $4}') 0x$(objdump -h $file | grep .text | awk '{print $5}')" >/dev/null 2>&1
# 比对磁盘文件与内存镜像哈希
HASH_DISK=$(sha256sum $file | awk '{print $1}')
HASH_MEM=$(sha256sum /tmp/mem_$pid 2>/dev/null | awk '{print $1}')
if [ "$HASH_DISK" != "$HASH_MEM" ]; then
echo "[严重告警] $file 进程$pid内存镜像与磁盘文件不一致,疑似页缓存篡改入侵" >> /var/log/suid_memory_warn.log
fi
rm -f /tmp/mem_$pid
done
done
8.3 审计系统规则补充配置
新增audit规则监控用户命名空间创建、tc、ipsec调用行为,写入/etc/audit/rules.d/cve_kernel.rules:
# 监控unshare创建用户命名空间
-a exit,always -F arch=b64 -S unshare -F a2=0x10000 -k user_namespace_create
# 监控tc系统调用
-a exit,always -F arch=b64 -S socket -F a0=16 -k tc_netlink
# 监控IPsec隧道配置
-w /usr/sbin/ip -p x -k ipsec_config
重载audit规则生效:augenrules --load
九、入侵事后溯源排查流程
主机检测出极高危风险,怀疑已经被入侵提权,按顺序执行排查操作,完整追溯攻击痕迹。
- 执行批量检测脚本确认内核、模块、sysctl基线状态;
- 读取/var/log/kernel_attack_warn.log、suid_memory_warn.log查看内存篡改告警;
- 审计日志筛选user_namespace_create标记,定位创建命名空间的用户、时间;
- 查找/home目录、/tmp、/dev/shm下遗留的PoC脚本、恶意TC配置文件;
- 检查历史bash历史记录,检索tc、unshare、setns、vmsplice关键词;
- 对比SUID程序内存磁盘哈希,确认是否发生过页缓存篡改;
- 清理恶意文件,执行二级加固阻断攻击链路,业务低峰窗口升级内核;
- 全集群批量巡检,排查同配置主机是否存在同类入侵痕迹。
十、容器云平台专项风险说明
多数运维存在误区:容器隔离可以抵御本地内核提权漏洞。容器仅隔离用户态资源,宿主机内核统一提供调度、内存管理能力。
容器内部普通用户创建命名空间、加载网络组件,依旧能触发两类漏洞篡改宿主机页缓存,直接获取宿主机root权限,横向渗透全部容器与主机业务数据。
容器平台强制落地两条规则:
- 所有业务容器丢弃CAP_NET_ADMIN能力;
- 宿主机统一关闭无特权用户命名空间,同步黑名单act_pedit、esp模块。
结尾互动
- 你们线上服务器主要使用哪个发行版内核,是否已经遇到过页缓存类无痕提权入侵?
- 企业内部文件完整性监控工具只用AIDE/Tripwire的,有没有配套内存校验方案?


被折叠的 条评论
为什么被折叠?



