标题 | 简介 | 类型 | 公开时间 | ||||||||||
|
|||||||||||||
|
|||||||||||||
详情 | |||||||||||||
[SAFE-ID: JIWO-2024-2553] 作者: 闲云野鸡 发表于: [2020-02-05]
本文共 [470] 位读者顶过
简介
CVE-2019-1215是ws2ifsl.sys中的一处UAF漏洞,原POC中,主要通过提前释放+堆喷的方式,修改函数执行流程,造成任意内存写的作用。[出自:jiwo.org]
Windows 10 18362.30 x64 ws2ifsl.sys中SocketFile和ProcessFile对象的分配
在驱动的DispatchCreate函数中,驱动根据上层传入的字符串,判断初始化的对象类型:
驱动通过FileObject的FSContext对象,区分对象是SocketFile还是ProcessFile
(2)CreateSocketFile函数中的 SocketFile初始化:
ws2ifsl.sys中SocketFile和ProcessFile对象的释放释放的位置在DispatchClose函数中,驱动根据FSContext头4个字节的硬编码内容,分别进行释放操作:
procData中的KAPC初始化在调用CreateProcessFile初始化ProcessFile时,内部会调用InitializeRequestQueue初始化一个APC队列。位置为procData+0x30处:因此procData的主要结构如下,我们的目标,便是在提前释放后利用堆喷,修改KernelRoutine指向我们希望执行的函数(这个函数最好能够进行内存读写的功能)达到利用的目的。
procData中的APC分发每次在向SocketFile下发读写操作时,驱动会调用DoSocketReadWrite函数,DoSocketReadWrite会先通过socketData获取procData,然后调用QueueRequest,最终调用SignalRequest利用procData中的KAPC分发APC。
漏洞根本原因 提前关闭了ProcessFile句柄,会导致procData提前释放。但是在SocketFile如果之前有下发读写操作时,procData中的KAPC结构依然在使用,这样在下一次APC调度的时候,造成UAF。 利用步骤 (1)分配好ProcessFile和SocketFile。(2)提前释放ProcessFile,并往SocketFile中写数据。 (3)利用堆喷,占坑PorcessFile释放的位置,其中的关键逻辑是伪造KAPC结构,避免系统检查异常导致蓝屏。 (4)调用NtTestAlert强制分发APC,触发任意写,破坏token,之后注入winlogon完成提权。 利用过程 1. 分配好ProcessFile和SocketFile,没什么可说的。
在驱动调用CreateProcessHandle初始化完后,procData的结构如下,大小为0x120。
注意procData+0x30处的KAPC结构,初始化完毕以后如下。
2. 关闭ProcessFile句柄,并往SocketFile中写数据,之后关闭SocketFile句柄,触发提前释放操作。
释放以后的内存状态如下:
3. 利用堆喷,占坑ProcessFile释放的位置,其中的关键逻辑是伪造KAPC结构,同时要避免系统检查异常导致蓝屏。
同时占坑的内容为我们精心构造的KAPC结构,我们构造的目的主要有两个:
我们在构造的时候,只需要将这两个参数,构造成我们想写的地址,和写的内容即可。 这里我们构造的写入地址为当前进程的Token位,目的是启用Privileges的Present和Enabled位(原POC中使用0xffffffffffffffff覆盖)
(2)绕过内核的安全检查
堆喷成功以后,对应的APC结构如下图(PS.原POC将NornalRoutine指定为xHalTimerWatchdogStop,其只有一条ret指令,目的是为了不进行任何处理操作)
4. 调用NtTestAlert强制分发APC,触发任意写,破坏token,之后注入winlogon完成提权。
触发以后的效果,可以看到成功的向Present和Enabled位写入了0xffffffffffffffff,并且可以注入winlogon进程,达到提权的效果。
系统补丁
参考第二步的利用堆栈。因为根本原因是因为ProcessFile对象提前释放导致的,所以,微软的修改方法就是在初始化ProcessFile时,在procData增加一个内部引用计数,初始化为1。
|