一个利用NtUserHardErrorControl的内核漏洞

作者:Sec-Labs | 发布时间:

项目简介

一个利用NtUserHardErrorControl的内核漏洞,将一个线程提升到KernelMode,实现任意的内核R/W及以上。

项目地址

https://github.com/SecIdiot/ANGRYORCHARD

摘要

ANGRYORCHARD是一个概念证明,利用NtUserHardErrorControl调用,在Microsoft Windows 7至11上实现任意R/W。该漏洞本身适用于所有版本的Windows 7到11,而在较新版本的Windows上,由于James Forshaw描述的KnownDLLs漏洞的服务和itm4n在2022年7月开发的PoC,在没有第三方问题的情况下,已经不容易达到。该bug本身位于CSRSS内,所以任何获取CSRSS的手段都将允许攻击者利用受影响的问题。

这个概念验证被设计成一个ReflectiveDLL,并且必须被注入到一个有特权的SYSTEM进程中才能正常运行。在执行时,该漏洞会根据版本直接将漏洞注入CSRSS,或者提升到PPL来注入漏洞代码,如果它可以的话。一旦代码被注入,该漏洞将调用NtUserHardErrorControl将KTHREAD.PreviousMode递减到初始漏洞阶段线程的0

分析报告

该错误本身存在于win32k系统调用NtUserHardErrorControl中,它处理传递给它的任意手柄的方式。据观察,当调用NtUserHardErrorControl时,控制代码设置为HardErrorDetachNoQueue,函数NtUserHardErrorControlxxxHardErrorControlxxxRestoreCsrssThreadDesktop在调用CloseProtectedHandle(后来的ObfDereferenceObject)前不会对句柄进行验证。

e7ecc3be44104750

展示HardErrorDetachNoQueue到xxxRestoreCsrssThreadDesktop的控制流程

db546b2a3d104804

展示了在CSRSS中导致实际 "错误 "的原因

幸运的是,对我来说,实现提升是相对微不足道的。我观察到,当执行从用户模式到内核模式的转换时,线程的PreviousMode被认为是调用者是否来自内核模式的有效指标。因此,通过传递KTHREAD对象的PreviousMode字段的地址,并考虑到OBJECT_HEADER中各自成员的偏移量将被递减,我能够成功地迫使当前线程的PreviousMode(最初设置为UserMode)被递减为KernelMode。

有了这个新的权限,我就能像内核调用者一样轻松地使用可用的系统调用,而不需要所有的验证检查,这些检查以前会阻止我与内核内存(如虚拟内存,甚至是来自 \Device\PhysicalMemory 对象的物理内存)交互。有了这个,我们甚至可以注入一个无符号的rootkit,不管HVCI / VBS是否被配置;)。

标签:漏洞分享