LinuxNetfilter匿名集合UAF漏洞(CVE-2023-32233)复现与利用分析

admin 2026-03-18 21:03:00 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入解析Linux内核Netfilter子系统CVE-2023-32233漏洞。漏洞源于匿名集合生命周期管理缺陷导致UAF,作者利用批处理事务与延迟机制构造DoubleFree,通过堆喷射绕过KASLR并劫持控制流实现提权。文章详述从环境搭建到ROP利用的全链路过程,包含代码分析与调试细节,技术深度高且实战性强,适合内核安全研究。 综合评分: 90 文章分类: 漏洞分析,二进制安全,实战经验,漏洞POC


cover_image

Linux Netfilter 匿名集合 UAF 漏洞 (CVE-2023-32233) 复现与利用分析

a2ure a2ure

看雪学苑

2026年3月11日 18:08 上海

CVE-2023-32233 揭示了 Linux 内核 Netfilter (nf_tables) 子系统中一个关键的 Use-After-Free (UAF) 逻辑缺陷。该漏洞的核心在于内核在处理“匿名集合”(Anonymous Sets)的生命周期时存在设计疏忽。通过构造特定的批处理事务并利用内核处理大量数据时的延迟,攻击者可以在匿名集合仍被规则引用的情况下,诱导内核将其提前释放。利用这一不稳定的内存状态,攻击者可以实现稳定的堆喷射与类型混淆,进而绕过 KASLR 防护并劫持内核控制流。

#

背景知识介绍

匿名集合 (Anonymous Sets)

在 Linux Netfilter 的nf_tables框架中,集合(Set)用于存储数据以供规则高效匹配。匿名集合(带有NFT_SET_ANONYMOUS标志)通常作为规则中lookup等表达式的附属品自动生成。其生命周期理论上应与规则严格绑定:规则创建时增加引用计数,规则删除时减少引用。

漏洞原理分析

漏洞根源于nf_tables_deactivate_set函数在事务准备阶段(NFT_TRANS_PREPARE)仅递减了引用计数set->use,却未执行解绑(unbind)操作。

// net/netfilter/nf_tables_api.c
voidnf_tables_deactivate_set(..., enum nft_trans_phase phase) {
switch (phase) {
case NFT_TRANS_PREPARE:
        set->use--; // 仅递减计数
return;     // 逻辑缺陷:未进行 unbind 便直接返回
// ...
}

这导致一个计数已归零、逻辑上应销毁的对象依然残留在全局链表中。通过在同一个 Batch 事务中精心编排“删除规则 -> 显式删除集合”的操作序列,可以诱导内核对同一个物理对象执行两次销毁流程,从而将 UAF 演变为 Double Free。

漏洞利用过程详解

CVE-2023-32233 的复现是一场精密的对象生命周期操纵艺术。在深入细节之前,下图展示了整个利用逻辑的核心路径,包括对象释放与抢占的顺序。

我们通过exploit.c将这一艺术转化为稳定的提权原语。

1. 基础环境构建与精准堆排布

利用的第一步是在内核中构建一个受控的 Netfilter 环境并进行精密的堆内存布局。CVE-2023-32233 的核心矛盾在于:当一个匿名集合(Anonymous Set)被规则引用时,虽然其生命周期应与规则绑定,但攻击者可以通过特定的批处理序列,在规则被标记删除后、集合正式解绑前,利用逻辑缺陷显式地触发集合的删除流程。

为了实现这一目标,我们首先通过pwn_prepare函数建立 nftables 的逻辑框架。这包括创建一个独立的主表testfirewall,并在其中定义两个关键链:pwn_lookup_chain(OUTPUT) 用于存放最初引用受害者集合的规则,而pwn_log_chain(INPUT) 则预留给后续的堆喷射操作。这种分层隔离不仅条理清晰,更确保了漏洞触发过程不会干扰系统的正常网络功能,为后续的内存操作提供了一个稳定的“手术台”。

static void pwn_prepare(struct mnl_socket *nl) {
pwn_create_table(batch, seq++); // 创建实验主表
pwn_create_chain(batch, seq++, pwn_lookup_chain); // 承载受害者规则
pwn_create_chain(batch, seq++, pwn_log_chain);    // 用于后续对象喷射
}

在实际调试过程中,为了验证堆排布的效果并精确定位受害者集合s_a的内存地址,我们可以在内核源码的net/netfilter/nf_tables_api.c:6145处打入断点。这里的目的是为了观察elem.priv,它指向了我们目标集合对应的nft_rhash_elem内容。通过 GDB 的输出可以看到,此时处理的正是我们预设的目标集合 “s_a”,这证实了基础环境构建的准确性。

紧随其后的是至关重要的堆整理(Heap Grooming)阶段。为了确保受害者对象落在可预测的内存位置并具备特定的溢出属性,我们执行pwn_uaf_spray函数。该函数通过循环喷射大量匿名集合来清理 SLUB 分配器的空闲列表(Freelist),迫使内核向伙伴系统申请全新的 Slab 页面。在这一喷射序列的中段,我们分配受害者集合s_a(即代码中的pwn_lookup_set)。此处的一个关键技巧是通过userdata将该对象的大小调整为 0x100 字节,使其精确落入kmalloc-256缓存池。

为了深入观察这个匿名集合在后续 Double Free 过程中的状态变化,我们需要利用硬件断点进行精细监控。通过命令p &set->ops获取ops指针格在内存中的绝对地址(例如0xffff888102bf74c0),随后设置硬件监视点:watch *0xffff888102bf74c0。这样做是因为在触发漏洞时,受害者内存块会被释放并可能被另一个“竞争集合”(Race Set)占领。监控ops成员的变化,能够让我们在复杂的事务提交流程中,精准地捕捉到对象被重新占用或二次释放的瞬间。

环境准备的最后一步是通过pwn_create_lookup_rule创建一条引用s_alookup规则。此时,受害者集合s_a的引用计数(use)变为 1,它在逻辑上已正式成为规则的一部分。这一步是整个利用链条的“挂钩”点:只有建立了这种引用关系,我们才能在后续的事务处理中,利用nf_tables_deactivate_set函数的逻辑缺陷,强行触发对该集合的非法释放,从而打开通往 Use-After-Free 的大门。

2. 操控时空:构造执行延迟 (Manipulating Time: The Delay Mechanism)

单纯的并发竞争往往难以跨越微秒级的内核指令间隙,因此我们需要一种机制来人为地“拉伸”内核的执行时间。在攻击准备阶段,我们通过pwn_delay_spray_set_elem函数向一个名为set_delay的辅助集合中预先填充了海量元素(数量高达0x300 * 0x800)。这个庞大的集合就像是一个蓄势待发的“时间锚”。

当我们在后续的攻击事务中请求删除这个集合时,内核被迫陷入漫长的内存释放循环中,必须逐个清理这些元素。这个精心构造的“停顿”操作,就像是插入齿轮中的一根撬棍,强行将内核的处理流程卡滞在特定的事务提交阶段。这产生了长达数十毫秒的执行延迟,为用户态的后续操作赢得了宝贵的“子弹时间”,使得原本稍纵即逝的竞争条件变得稳定可控,让我们有足够的时间从容地进行堆内存的抢占与布局。

3. 致命一击:触发 Double Free 与对象重叠 (Triggering Double Free & Object Overlap)

万事俱备,利用流程进入了最关键的阶段。在正式触发 Double Free 之前,通过 GDB 调试观察nft_rhash_elem的内容,可以进一步确认受害者集合s_a的内存排布。如下图所示,elem.priv准确指向了我们的目标匿名集合。

接下来的核心挑战在于如何在两次释放的微小间隙中完成内存抢占。我们的策略是:在s_a被第一次释放后,立即通过另一个事务创建一个“竞争集合”(Race Set)。这里有一个极其精妙的设计:我们将race_set的名称(name)构造为一个大小属于kmalloc-cg-256的字符串。

由于s_a刚刚被释放,内核分配器极大概率会将race_set->name分配到s_a原有的内存槽位上。通过在nf_tables_newset函数处设置断点,我们可以精准地捕捉到这个覆盖瞬间。

此时原本存放s_a结构体的空间已经被race_set的名称字符串所覆盖。为了进一步监控这块内存的变化,我们获取name的地址(例如0xffff888102af4f00)并设置硬件监视点:watch *0xffff888102af4f00

当利用程序继续执行add chain操作时,这个监视点会被断下,此时正好处于memcpy用户数据(udata)到内核空间的时刻。

执行finish结束memcpy后,观察内存状态可以清晰地看到原本的name字段已经被我们完全可控的chain->udata所填充。

至此,受害者集合race_setname指针已经变成了一个指向“幽灵内存”的悬垂指针,且该内存中的数据已被我们占位。

随后,漏洞逻辑触发了对s_a的第二次释放。由于之前的重叠,内核实际上释放的是race_set->name的内存。这就在kmalloc-cg-256缓存池中制造了一个空闲槽位。为了引入更具“价值”的对象——nft_rule,我们在这里执行了一个关键的步骤:主动释放race_set

通过调用pwn_uaf_del_set,内核会显式释放race_set->name。由于物理地址重叠,这实际上将chain->udata所在的内存块再次放回了空闲列表。

接下来的目标是让nft_rule对象占领这个空位。由于nft_rule及其表达式(如counter)同样使用该缓存池,我们可以通过喷射规则来触发占位。当内核执行到规则插入 RCU 链表的关键步骤时,新的规则对象已经精准地坐落在之前被释放的内存块上。

此时,利用进入了信息泄露阶段。通过NFT_MSG_GETCHAIN接口读取该链表的udata,原本存放用户数据的内存中,现在赫然出现了nft_counter_ops的指针。通过解析这些数据,我们能够成功提取出这个内核符号地址,从而计算出内核基址(kbase),实现 KASLR 的完美绕过。

下图展示了nft_rule及其内部nft_expr的具体布局,这也正是我们能够通过重叠内存读取到关键指针的原因。

4. 权力交接:劫持与提权 (Precision Hijack & Root Shell)

在成功获取内核基址与堆地址后,利用进入了最后的劫持阶段。这一阶段的核心在于通过再次的对象重叠,在内核中植入一个我们完全控制的“伪造对象”。

我们利用泄露的信息,在用户态构造了一个精密的 ROP 链。整个提权逻辑如下:

定位 Init 进程:通过find_task_by_vpid(1)获取 init 进程的task_struct地址。

逃逸命名空间:调用switch_task_namespaces(init_task, &init_nsproxy),将当前进程的命名空间切换回全局初始命名空间,从而绕过容器或沙箱限制。

获取 Root 权限:执行commit_creds(&init_cred),将当前进程的凭证替换为系统管理员权限。

维持稳定:最后调用vfork()并进入一段长时间的延迟,以确保提权后的环境能够稳定运行。

为了触发这个 ROP 链,我们利用pwn_uaf_spray_chain_fake_rule喷射一组精心构造的fake_nft_rule结构体。在这些伪造结构体中,我们篡改了操作钩子(Ops),将其指向一个关键的跳转 Gadget(如push rax ; pop rsp ; ret),而rax此时正好指向我们布置好的 ROP 链。

当一切准备就绪,我们只需发起一个 handle 为0xffff的删除规则请求。内核在遍历链表并尝试执行删除前的清理逻辑时,会毫无察觉地调用那个被篡改的指针。瞬间,内核栈被劫持到 ROP 链上,提权逻辑在内核态高速执行。随着win()函数在用户态被调用,一个具有 root 权限的 Shell 跃然屏上,宣告了这场内核生命周期操纵艺术的最终胜利。

补丁分析与总结

官方补丁通过在nf_tables_deactivate_set中增加状态检查,确保了集合在引用计数归零时被正确解绑,从而堵住了这一逻辑漏洞。CVE-2023-32233 的复现过程不仅展示了 Netfilter 子系统中复杂的对象生命周期管理风险,更生动地演绎了如何通过精密的堆风水(Heap Feng Shui)和时间操控(Time Dilation),将一个看似受限的 UAF 漏洞转化为稳定的内核提权利器。这无疑是内核漏洞利用艺术的一次精彩展示。

#

看雪ID:a2ure

https://bbs.kanxue.com/user-home-991890.htm

*本文为看雪论坛优秀文章,由 a2ure 原创,转载请注明来自看雪社区

往期推荐

从ANGR-CTF项目入手ANGR和符号执行技术

AI时代-逆向工作者该如何用好这一利器

EXIF解析缓冲区溢出漏洞分析与利用

从C到Pwn:栈溢出漏洞利用实战入门

Android-ARM64的VMP分析和还原

球分享

球点赞

球在看

点击阅读原文查看更多


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:看雪学苑 a2ure a2ure《Linux Netfilter 匿名集合 UAF 漏洞 (CVE-2023-32233) 复现与利用分析》

    评论:0   参与:  0