前言
内网运维、云平台安全岗最近持续收到主机异常权限告警。多数告警溯源后指向同一类攻击手段:普通业务用户登录服务器,无磁盘写入痕迹、不修改系统二进制哈希,直接拿到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 问题代码片段还原
内核原始漏洞代码简化提取,仅保留缺陷逻辑,删除无关边界校验代码:
staticinttcf_pedit_act(struct sk_buff *skb, conststruct 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.shclearecho "=============================="echo "Linux双内核高危提权漏洞检测工具"echo "漏洞编号:CVE-2026-46331 pedit COW / CVE-2026-43503 DirtyClone"echo "=============================="# 获取纯净内核版本,剔除发行版后缀RAW_KERN=(echo RAW_KERN"echo "标准化比对内核版本:2" "2"}ver_lt() { ! ver_ge "2"}# 风险标记初始化FLAG_PEDIT=0FLAG_DIRTYCLONE=0FLAG_UNPRIV_USERN=0FLAG_ACT_PEDIT_MOD=0FLAG_ESP_MOD=0# 判断CVE-2026-46331风险区间 5.18 <= ver <7.1if ver_ge "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.1if ver_lt "(sysctl net.user_namespaces.unprivileged_userns_clone 2>/dev/null | awk '{print 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"fiif 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=TOTAL_RISK -ge 2 ] && [ FLAG_ESP_MOD -eq 1 ]; then echo -e "\033[41;37m【极高危】双漏洞全部存在,双攻击模块加载,可无痕绕过文件完整性检测完成root提权,立即执行临时加固!\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"fiecho "=============================="
脚本使用操作步骤
- 新建空白文件,复制完整代码粘贴保存为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=(echo RAW_KERN" echo "KERN_STD: 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" "7.1"; then FLAG_PEDIT=1 echo "RISK_PEDIT: 1" else echo "RISK_PEDIT: 0" fi if ver_lt "(sysctl net.user_namespaces.unprivileged_userns_clone 2>/dev/null | awk '{print 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
chmod 700 /sbin/tcchown root:root /sbin/tc
7.2 二级加固:中长期基线配置(无需内核升级,永久生效)
写入系统配置文件,重启主机配置自动加载,作为内核升级前过渡防护手段。
echo "net.user_namespaces.unprivileged_userns_clone=0" >> /etc/sysctl.confsysctl -p
- 内核模块黑名单,禁止开机加载act_pedit、esp 新建/etc/modprobe.d/block_cve_2026.conf,写入内容:
blacklist act_peditinstall act_pedit /bin/falseblacklist espinstall esp /bin/falseblacklist xfrminstall xfrm /bin/false
更新内核引导镜像,确保黑名单生效 Debian/Ubuntu:update-initramfs -u RHEL/Fedora:dracut -f /boot/initramfs-(find /usr/bin /bin -perm -4000 -type f 2>/dev/null)for file in (lsof 2}' | grep -v PID | sort -u) for pid in pid -ex "dump memory /tmp/mem_(objdump -h 4}') 0xfile |grep .text |awk'{print (sha256sum 1}') HASH_MEM=pid 2>/dev/null |awk'{print HASH_DISK"!="file 进程pid donedone