译者注:本文适合初学者阅读,强力建议优先扩展阅读文末参考文献。围绕GDI相关的漏洞、利用策略非常丰富,各大站点转转,会有不错的收获。聪明人懂得自扩展。
每一次当我在一些特别的事情上开展工作时,它们都会给我钥匙来打开新大门。
不久之前我遇到一个和漏洞相关的字体,那是一个已被开发的0day漏洞。该漏洞在一个ATFMD.SYS驱动程序中[1],我多少熟悉一些。
但这一次抓住我眼球的是,漏洞利用程序通过一种高雅简明的方式实现了系统提权。
这一技术的机理涉及了一个对表现为位图(SURFOBJ)的内核数据结构打补丁,使它变成一个强力的任意读写原语。
Alex lonescu在他的2013 Win32k课题的精彩演讲中分享了内存区域[2]。但是他没有提及这一个,实际上我所能找到的此前唯一提到该技术的是2015年7月由Keen Team所提及[5]。
简单说明,此下讨论的每种数据结构和偏移都以Windows 8.1 x64为准。
注意看GdiSharedHandleTable
,用户映射的Win32k!gpentHmgr
的一部分。他是一个结构体数组,成员一一对应进程中的每个GDI对象。
可以通过PEB.GdiSharedHandleTable
来定位指针:
GdiSharedHandleTable
的每一项使用下列结构:(这些结构都是此前Feng Yuan和ReactOS所记载的64位版本[3]&[4])
通过一个GDI句柄,我们可以知道表中的每一项地址像这样:
pKernelAddress
指向表项的BASEOBJECT
头,后面跟随着一个特定的结构,这取决于它的wType。
对一个位图来说,后面的特定结构看起来像这样:
对32位的BMF_TOPDOWN
位图来说我们所关心的就是pvScan0,一个指向像素数据(第一个扫描行的起始)的指针,用户模式可以使用的GetBitmapBits
和SetBitmapBits
通通使用它操作。
注意到尽管我们不能通过用户模式代码访问那些结构体成员,我们依然可以自己计算地址。
这意味着我们可以推敲一定量的ring0漏洞并把它们转换成相当可靠的利用程序,完全的绕过当前Windows内核保护机制。
举个例子,比如我们有一个ring0层任意地址写任意值的漏洞且只能触发一次。你可以这样做:
啊?
现在我们将一次任意地址写任意值漏洞变成了读/写任意虚拟地址漏洞,我们可以多次使用它。
我们可以用它来修整污染的池块、窃取进程token以及完成一系列的有趣操作!
是时候把功能包裹成可用代码了:
我们想用上面的代码来窃取System进程的token。
我们需要:
这是帮助我们处理的代码:
gConfig
需要一些解释。一些未文档化的结构在不同Windows版本间有所变化。EPROCESS
就是其中之一,这意味着成员的偏移在不同Windows版本间也会有所变化。
因为我们需要获取EPROCESS
的UniqueProcessId,ActiveProcessLinks和Token三个字段,我们需要找出一种方式来知晓它们正确的偏移。
为了简化示范我选择一个包含那些在不同Windows中预设置的结构体:
注意我们实际上并没存储ActiveProcessLinks偏移,因为它一直为UniqueProcessId+8。
因此,对Windows 8.1 x64来说我们可以像这样预设置gConfig:
好了,现在我们偷取Token:
当我搜索GDI数据结构时我发现我缺少一个合适的工具来感应它们,特别是当我需要去在所有地方喷射GDI对象的时候。
我知道gdikdx.dlll
,但那已经是10年前的事了。在我的认知范畴,没有什么能在x64系统上替代它工作。因此我制作了一些对我以及他人可能有用的工具。
这是个WinDbg/Kd插件,用于转储关于GDI句柄表的信息以及它涉及的内核结构。
这是个独立的应用程序,它加载通过GDIObjDump转储的二进制数据并显示一个表示GDI表的图例。它允许你使用多种方式去排序和过滤GDI表项,单击单一元来查看它们的内核数据结构中的内容。
通过GDIObjDump项目页[6]下载它们。
[1]{MS OpenType CFF Parsing Vulnerability}
[2]{I Got 99 Problem But a Kernel Pointer Ain't One - Alex lonescu}
[3]{Windows Graphics Programming: Win32 GDI and DirectDraw - Feng Yuan}
[4]{Win32k/structures(ReactOS)}
[5]{Windows Kernel Exploitation: This Time Font hunt you down in 4 bytes - Keen Team}
[6]{GDIObjDump project page}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)