CVE-2022-2588 Dirty Cred漏洞分析与复现
CVE-2022-2588 Dirty Cred漏洞分析与复现
Arahat0 看雪学苑 2024-03-30 18:00
1. 漏洞简述
◆漏洞名称:Dirty Cred
◆漏洞编号:CVE-2022-2588
◆漏洞类型:Double Free
◆漏洞影响:Linux 本地提权
◆CVSS评分:7.8
◆基础权限:需要
2. 组件概述
漏洞函数是route4_change()
,用于初始化和替换route4_filter
对象。使用handle
作为id来区分不同的route4_filter
,如果存在某个handle
之前已被初始化过(fold
变量非空),就会移除旧的filter
,添加新的filter
;否则直接添加新的filter
。
3. 漏洞利用
由于将route4_filter
对象从链表中删除和释放时的检查条件不一致,导致该对象被释放后仍存于链表中,后面可以触发 Double Free,本地攻击者利用该漏洞会导致系统崩溃,可能会造成本地特权升级问题。
4. 漏洞影响
影响Linux Kernel版本:
◆Linux Kernel版本 >= 2.6.12
◆Linux Kernel版本 <= 5.19.1
5. 解决方案
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9ad36309e2719a884f946678e0296be10f
安装 Kernel:
◆怕麻烦的可以在bsauce大佬的仓库去取:
https://github.com/bsauce/kernel-exploit-factory/tree/main/CVE-2022-2588
编译选项:
◆CONFIG_BINFMT_MISC=y(否则启动VM时报错)
◆CONFIG_USER_NS=y(触发漏洞需要 User Namespace)
◆CONFIG_NET_CLS_ROUTE4=y(漏洞函数所在的模块)
◆CONFIG_DUMMY=yCONFIG_NET_SCH_QFQ=y(breezeO_o 提供的两个编译选项,触发 poc 需要用到)
◆CONFIG_NET_CLS_ACT=y/CONFIG_NET_CLS_BASIC=y(默认已开启)
◆CONFIG_NET_SCH_SFQ=y(exploit 中触发漏洞需用到 sfq 随机公平队列)
◆CONFIG_NET_EMATCH_META=y(exploit 中堆喷对象时需要用到)
1.前置知识
内核凭证 Credential
Kernel 凭证是 kernel 文档中定义的 kernel 中携带特权信息的特征,表示权限和对应的能力,主要分为:
◆task 凭证(struct cred
):其中存放了一个 task 的权限信息,例如 GID、UID 等等。如果能任意修改一个低权限进程的 cred 结构体,那么我们就可以将该进程提权至高权限(例如 root)。
◆open file 凭证(struct file
):存放一个文件的部分权限信息,例如 read & write 权限等。如果一个低权限用户可以任意修改高权限文件(例如/etc/passwd
),那么同样也能造成提权的目的。
Slab 的两种内存缓存
众所周知,Linux 内核主要使用 slab 分配器来进行内存分配,slab 分配器中主要维护了两种内存缓存(即可以理解成两套作用不同的内存分配方式):
◆dedicated cache(专用缓存)
:这里的内存是用于分配给内核中的常用对象,在该缓存中被分配的结构体将始终保持初始化状态,以便于提高分配速度
◆generic cache(通用缓存)
:通用缓存,大多数情况下其内存块的大小与 2 的幂次方对齐。
这类cred
和file
结构体等credential
对象都是在dedicated cache
中分配,而大多数内存漏洞发生的地方都是在generic cache
中。
使用sudo cat /proc/slabinfo
可以查看 slab 分配器的具体信息。
◆generic cache
:在名称中带有kmalloc。
◆dedicated cache
:拥有特殊的名字。
2.漏洞与利用
漏洞点
◆将route4_filter
对象从链表中删除和释放时的检查条件不一致。
◆导致该对象被释放后仍存于链表中。
大致步骤:
◆释放存在漏洞的非特权凭据。
◆在释放的内存插槽中分配特权凭据。
◆以特权用户身份操作。
具体步骤:(本例是采用file
对象完成利用,也可以采用cred
对象)
◆打开可写的文件/tmp/x
,就会分配可写的file
对象,在通过写许可检查之后后,进行实际写操作之前暂停。
◆利用漏洞释放该file
对象。
◆打开只读文件/etc/passwd
,就会分配新的file
对象,占据旧的file
对象,继续写入就能往只读文件写入内容(例如写入hacker:x:0:0:root:/:/bin/sh
就能提权)。
3.需要解决的问题
(1)如何将内存破坏漏洞,转换为能够置换file object
的原语。
(2)如何延长文件的检查文件写权限 – 实际写入数据的竞争窗口。
(3)如何创建高权限的file object
,来置换先前被释放的低权限file object。
4.对应的解决措施
(1)置换内核凭证
一般就是如下三种方式:
◆Out Of Bound Write:尝试越界写入下一个结构体的凭证字段,将其替换为高权限的凭证(例如:request_key_auth->cred
)。
◆Use After Free:使用高权限的凭证来“占据”低权限的凭证。
◆Double Free:最终可以达到两个指针共同指向一个凭证的效果。
(2)延长竞争窗口
由于credential
的替换需要一些时间,因此如果能延长这个竞争窗口,那就能非常成功的进行漏洞利用,其中Userfaultfd
和 FUSE
,这两种机制都允许用户无限延长竞争窗口。
◆Userfaultfd:在多线程程序中,userfaultfd
允许一个线程管理其他线程所产生的Page Fault
事件,当某个线程触发了Page Fault
,该线程将立即睡眠,而其他线程则可以通过userfaultfd
来读取出这个Page Fault
事件,并进行处理。
◆FUSE:一个用户层文件系统框架,允许用户实现自己的文件系统,用户可以在该框架中注册handler
,来指定应对文件操作请求(可以在实际操作文件之前,执行handler
暂停内核执行,尽可能地延长窗口)。
◆File Lock:使用锁定暂停内核执行。
(3)分配特权对象
由于 Dirty Cred 十分需要控制privilege credential
对象的分配时机,控制该对象的分配成为了一个关键点
用户层中:
◆大量执行Set-UID
程序(例如sudo
),或者频繁创建特权级守护进程(例如sshd
),从而创建privilege cred
结构体
◆使用 ReadOnly 方式来打开诸如/etc/passwd
等特权文件
内核层中,当内核创建新的kernel thread
时,当前kernel thread
将会被复制,这时其privileged cred
结构体也会被拷贝一份
有两种方法可以做到这点:
① 往kernel workqueue
中填充大量任务,动态创建新的kernel thread
来执行任务。
② 调用usermode helper
(一种允许内核创建用户模式进程的机制),一种最常见的应用场所是加载内核模块至内核空间中。
5.静态分析
◆route4_filter
对象:(大小为“144”,属于kmalloc-192
)
◆tcf_exts
对象的tc_action
条目:(包含32个tc_action
对象指针,属于kmalloc-256
)
◆有漏洞的代码:
◆使用handle作为 ID 来区分不同的route4_filter。
◆如果存在某个handle之前已被初始化过(fold变量非空),就会移除旧的filter,添加新的filter。
◆否则直接添加新的filter。
这里可以发现,将route4_filter对象从链表中删除和释放时的检查条件不一致:
◆从链表中删除的条件:
– 存在old filter
-
old handle不为 “0”
-
old new handle不同
◆从链表中释放的条件:
– 存在old filter
如果old handle == 0
,则不会在链表中删除但是会被释放,这就导致了一个 UAF。
6.利用思路
cross-cache:我们将释放某个kmalloc-256 cache page
,将该页归还给页管理器,然后分配file
结构来复用该页(filp cache
)。
◆分配一堆kmalloc-256
堆块,包含漏洞对象。
◆利用漏洞第1次释放漏洞对象,并释放一堆kmalloc-256
,以归还漏洞对象所在的页。
◆分配大量低权限file
对象来占据漏洞对象(cross-cache attack)。
◆利用漏洞第2次释放漏洞对象(低权限file
对象被释放)。
◆堆喷高权限file
对象来替换低权限file
对象。
◆利用 UAF 控制高权限file
对象。
7.官方补丁
借用其他师傅的表:
对应 exp 如下:
结果如下:
参考文章:
CVE-2022-2588 Double-free 漏洞 DirtyCred 利用
(
https://bsauce.github.io/2022/10/21/CVE-2022-2588/
)
浅析 Linux Dirty Cred 新型漏洞利用方式
(
https://kiprey.github.io/2022/10/dirty-cred/)
看雪ID:Arahat0
https://bbs.kanxue.com/user-home-964693.htm
*本文为看雪论坛精华文章,由 Arahat0 原创,转载请注明来自看雪社区
#往期推荐
2、Glibc-2.35下对tls_dtor_list的利用详解
3、对旅行APP的检测以及参数计算分析【Simplesign篇】
球分享
球点赞
球在看
点击阅读原文查看更多