首发于 NOSEC
想绕过Windows 10 KASLR?一条WinDBG命令足矣

想绕过Windows 10 KASLR?一条WinDBG命令足矣

Windows 10 1809内核ASLR绕过技术的演变

在内核地址空间布局随机化(KASLR)保护机制得以正确实现的情况下,直接获取内核驱动程序的基地址是不现实的,这给Windows内核的漏洞利用带来了极大的困难。为了绕过该防御机制,研究人员过去的研究重点通常都放在以下几种途径上面:通过内核地址泄漏来检索这些地址,或者通过特定的内核内存泄漏漏洞,或者使用通过池溢出(pool overflow)或write-what-where之类的内核漏洞来创建内核模式读取原语。不过,本文的重点则是使用内核模式读取原语绕过KASLR,因为这种类型的方法更加通用。

实际上,在KASLR安全机制的绕过与反绕过方面,一直是个猫鼠游戏:

在撰写本文时,已经有一年时间没见过新型的通用Windows内核利用技术问世了,这意味着Windows10的当前版本中的KASLR已经非常强大了。

从表面上看,这似乎是一件好事,但当我开始着手准备一个新的安全课程时,却让我有点为难:既然是新课程,如果还在介绍一年前就开始使用的、针对老版操作系统的老技术的话,好像有点说不过去。

所以,我开始在当前版本的Windows 10(代号为Redstone 5)上挖掘新型的KASLR绕过方法。功夫不负有心人,经过一番折腾,我终于找到了一个。

在这篇文章中,我将向您介绍在挖掘这种绕过技术过程中的一些关键步骤,正是借助于这些步骤,才帮我发现了尚未公布的KASLR绕过技术。

踏上征程

首先,请注意,通过使用众所周知的 EnumDeviceDrivers和 NtQuerySystemInformation API,攻击者能够以中等完整性级别来发动攻击,从而轻易绕过KASLR。因此,对于本文的其余部分,将假设执行的上下文是在低完整性水平下,或是在应用程序沙箱中进行的。

在以前版本的Windows 10中,可以使用多种通用方法来强制内核指针泄漏,包括使用来自线程环境块(TEB)的Win32ThreadInfo指针,泄漏兼容位图或利用桌面堆(Desktop heap)。对于这里介绍的绕过方法来说,我们将专注于使用桌面堆。

在Windows 10的Redstone 2版本中,微软删除了存放在桌面堆上分配内存的所有对象的内核模式地址的UserHandleTable,但幸运的是,桌面堆本身仍然是以用户模式映射的,使得我们仍然可以对其进行搜索并查找特定的对象。另外,由于像tagWnd这样的桌面堆对象通常包含一个头部,我们可以借助特定的dereference链,通过这个头部来获取一个KTHREAD结构,因此,我们可以设法触发内核模式指针地址泄漏,进而绕过KASLR。下面的清单1给出了相应的代码:

清单1:适用于Windows 10 Redstone 2版本的KASLR绕过技术

为了在Windows 10 Redstone5版本下进行测试,我们通过CreateWindowEx API创建了一个窗口,从TEB中的偏移0x828处获取用户模式映射桌面堆的地址,然后通过暴力搜索,在用户模式映射的桌面堆上查找Window句柄,以获取相应的偏移量——这实际上就是我在2017年的Black Hat USA大会上展示的一种技术。

图1:用户模式映射的桌面堆中的窗口句柄和位置

在Redstone 5之前,图1中的地址tagWnd将指向tagWnd内核对象的直接副本,该对象包含tagWnd对象的直接副本,该对象包含所有相关的内核模式指针,包括threadInfo指针。但是,如清单2所示,实际结果相去甚远:

清单2:用户模式映射桌面堆内的Windows对象

在Redstone 2版本中,清单2中突出显示的值将包含窗口对象名称的UNICODE_STRING结构。这意味着映射到上面突出显示的值的值通常包含窗口名称的UNICODE_STRING结构,该结构位于偏移量8处,即映射到地址0x20a177ab800的值通常包含指向该UNICODE字符串的内核模式指针。但事实并非如此。很明显,微软已经彻底修改了用户模式映射的桌面堆。

此时,为了更好地理解具体发生了什么变化,我不得不在内核空间中执行一些交叉检查。为此,我尝试查找桌面堆内核模式的基地址。在Redstone 5之前的版本,我们可以在桌面堆头部的偏移量0x28处找到该指针,并且,该指针可以从用户模式映射的桌面堆中读取。因此,我尝试通过调试器从TEB中偏移量0x828处手动获取该地址:

清单3:用户模式映射的桌面堆的头部

从上面的列表中我可以看到,现在用户模式映射桌面堆中偏移量为0x28处的QWORD的值为NULL。不过,我们可以在偏移量0x80处得到桌面堆的内核基地址,所以,我继续使用该偏移量进行分析。

清单4:桌面堆和Window内核模式地址的Delta值

由于用户模式映射的桌面堆是由SYSTEM线程进行更新的,所以,我预计内核空间中桌面堆的内容会与用户空间中显示的内容略有不同。但是,在检查两个桌面堆的内存(见清单3)时,WinDBG显示了完全相同(未经过滤)的内容!这意味着Microsoft对Desktop堆和相关API进行了彻底的修改。

更多的堆

为了弄清楚微软具体做了哪些修改,并确定攻击向量是否可行,我需要了解更多关于内核模式API如何在修改后的桌面堆上操作的相关信息。由于窗口名称(作为Unicode字符串存储在tagWnd对象中)通常比较容易识别(并且是用户可控的),因此,我调用了NTUserDefSetText API,试图更新该名称,并获得其实际的内核模式地址。为了跟踪执行情况,我在Win32KFull.sys中的NTUserDefSetText上设置了一个断点:

清单5:在NtUserDefSetText的prologue中看到的ValidateHwnd

在这里,我注意到了对ValidateHwnd的调用,它使用窗口句柄来定位内核模式tagWnd对象的地址。通常情况下,ValidateHwnd将返回内核桌面堆上的tagWnd的内存地址,但这又带来了另一个惊喜:

清单6:包含tagWnd对象的第二个桌面堆

如清单6所示,从ValidateHwnd接收的内核模式地址指向一个句柄为0x30502的对象,该对象与更新后的POC在用户空间中返回的Window句柄完全一致。所以,该对象包含的是内核模式指针,偏移量0x28处包含的是指向具有单独内存空间的指针,该内存空间也包含相同的窗口句柄。

由此得出的结论是,微软已经创建了多个桌面堆,并将对象内容存放到多个堆中,同时,只将内核模式指针的free版本映射到用户模式。这是一种非常好的方法,可以缓解用户模式中内核模式对象的滥用,从而加固KASLR。好了,这方面的内容就不多讲了,毕竟本文的主题是KASLR绕过技术。

与ASLR绕过所有方法一样,这里的关键也是要弄清楚在进程重启过程中随机化了哪些内容。在完成这些调查的过程中,我发现了一些重要的信息。首先,映射到用户模式的桌面堆的基地址始终以0x1400000结尾,重新启动后,只对高36位的内容进行了随机化处理。

其次,包含内核模式对象指针的桌面堆的地址也只是高36位(如清单7中的绿色所示)进行了随机化处理,这与映射到用户模式的桌面堆的地址的处理方式是一致的。之后的4 bit的内容始终等于0x4或0x6(见红色部分),而低24位则进行了随机化(以蓝色显示),这样就无法预测对象的仅内核模式桌面堆(kernel-mode only Desktop heap)的地址了:

清单7:仅内核模式桌面堆中的tagWnd对象的头部

这种区分似乎是合理的,只有内核模式的桌面堆包含指向用户模式桌面堆的指针。

固定值的使用似乎非常值得关注,因为它表明随机化是不彻底的。幸运的是,我在重新启动时发现了一个更加重要的线索。清单7中显示的tagWnd对象的仅内核模式的桌面堆部分表明偏移0x50处的指针指向另一个仅内核模式桌面堆,其内容是未知对象:

清单8:单独的桌面堆中的未知对象

这个对象让人感兴趣的是,低28位在重新启动时是一个固定值,即0x08308c0(以蓝色显示),而高36位是与用户模式共享的桌面堆(以绿色显示)。实际上,我们可以泄漏并计算包含内核模式指针的对象的绝对地址!

更有价值的是,从该对象的开头偏移0x10处的值是指向threadInfo结构的指针,这使我们可以使用原来的tagWnd KASLR绕过技术。threadInfo结构的偏移量0x0处包含指向KTHREAD的指针,其在偏移量02A8处包含指向ntoskrnl的指针。Dereference过程如清单9所示:

清单9:从未知对象指向ntoskrnl的指针

小结

在Windows10发布的Redstone 5版本中,微软完成了一项令人印象深刻的工程任务:将桌面堆分割成多个堆,并只允许用户模式查看与内核无关的内容。但是,它的随机化在实现方面存在使用静态值的缺陷,所以,如果攻击者能够读取任意内核模式内存的话,仍然能够绕过KASLR安全机制。

该KASLR绕过技术之所以能够得逞,是因为攻击者可以泄露内核模式对象地址中已经随机化处理后的36位,而低28位是静态的。与内核模式读取原语一起使用的内核模式对象的位置将指针泄漏给NTOSKRNL。

尽管原理比较复杂,但是要想绕过Windows 10 的Redstone 5版本中的KASLR防御机制,只要一条命令就行了:

清单10:利用一条WinDBG命令绕过KASLR

由于这种类型的安全问题与任何MicrosoftBug报告程序或指南都不匹配,因此,我尚未报告该问题。但是,我已经确认,由于某些设计的更改,这个问题在即将发布的19H1版本中将得到修复。


本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场

来源: 想绕过Windows 10 KASLR?一条WinDBG命令足矣

原文: offensive-security.com/

白帽汇从事信息安全,专注于安全大数据、企业威胁情报。

公司产品:FOFA-网络空间安全搜索引擎、FOEYE-网络空间检索系统、NOSEC-安全讯息平台。

为您提供:网络空间测绘、企业资产收集、企业威胁情报、应急响应服务。

两个鬼故事团结佳兴园孙姓宝宝起名大全男生起名网的孩子女孩起名字测试打分免费教育公司起名大全集翡翠店起名字起名网测名字打分游戏里起什么名字好听未来日记oad咬牙切齿的意思化工公司起什么名字好啊伪装学渣免费全文阅读未删减金宝宝起名软件哪个陈起名字见贤思齐是什么意思党员个人问题清单及整改措施带三点水的字起名有哪些终极笔记演员表联通大王卡19元套餐介绍属火的七画起名字青砖尺寸汉正街品牌服饰批发广场钱学森电影下载汽修厂起名剑鱼行动下载孙姓孩子起名大全男孩bt项目检讨书1000字莫晓蝶陆晨旭免费阅读无弹窗教育机构起名字大全少年生前被连续抽血16次?多部门介入两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”淀粉肠小王子日销售额涨超10倍高中生被打伤下体休学 邯郸通报单亲妈妈陷入热恋 14岁儿子报警何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言张家界的山上“长”满了韩国人?男孩8年未见母亲被告知被遗忘中国拥有亿元资产的家庭达13.3万户19岁小伙救下5人后溺亡 多方发声315晚会后胖东来又人满为患了张立群任西安交通大学校长“重生之我在北大当嫡校长”男子被猫抓伤后确诊“猫抓病”测试车高速逃费 小米:已补缴周杰伦一审败诉网易网友洛杉矶偶遇贾玲今日春分倪萍分享减重40斤方法七年后宇文玥被薅头发捞上岸许家印被限制高消费萧美琴窜访捷克 外交部回应联合利华开始重组专访95后高颜值猪保姆胖东来员工每周单休无小长假男子被流浪猫绊倒 投喂者赔24万小米汽车超级工厂正式揭幕黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发当地回应沈阳致3死车祸车主疑毒驾恒大被罚41.75亿到底怎么缴妈妈回应孩子在校撞护栏坠楼外国人感慨凌晨的中国很安全杨倩无缘巴黎奥运校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变王树国卸任西安交大校长 师生送别手机成瘾是影响睡眠质量重要因素国产伟哥去年销售近13亿阿根廷将发行1万与2万面值的纸币兔狲“狲大娘”因病死亡遭遇山火的松茸之乡“开封王婆”爆火:促成四五十对奥巴马现身唐宁街 黑色着装引猜测考生莫言也上北大硕士复试名单了德国打算提及普京时仅用姓名天水麻辣烫把捣辣椒大爷累坏了

两个鬼故事 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化