关于CVE-2018-8120的最新Windows提权漏洞分析
一、背景介绍
5月中旬ESET披露了其捕获的PDF文档样本中的两枚0-day漏洞,其中包含针对Windows系统的内核提权漏洞。该漏洞的漏洞编号为CVE-2018-8120,Windows已经提供安全更新修复此安全漏洞。天融信阿尔法实验室将以Windows Server 2003 32位系统为目标,详细介绍该漏洞成因、如何触发漏洞、以及如何使用该漏洞制作“本地应用程序权限提升”工具。
经验证,诸多版本的Windows系统均存在该漏洞,文末同时附带一份利用该漏洞制作的提权工具,以供学习。经测试该工具支持Win2003 x32/x64、WinXP x32、Win7 x32/x64, Win2008 x32/64。
1.1 漏洞描述
部分版本Windows系统win32k.sys组件的NtUserSetImeInfoEx()系统服务函数内部未验证内核对象中的空指针对象,普通应用程序可利用该空指针漏洞以内核权限执行任意代码。
1.2 受影响的系统版本
以下软件版本受到影响。未列出的版本要么超过其支持生命周期,要么不受影响。要确定软件版本或版本的支持生命周期,请查阅Microsoft支持生命周期。
Windows 7 for 32-bit Systems Service Pack 1
Windows 7 for x64-based Systems Service Pack 1
Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2008 for Itanium-Based Systems ServicePack 2
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 R2 for Itanium-Based Systems ServicePack 1
Windows Server 2008 R2 for x64-based Systems ServicePack 1
Windows Server 2008 R2 for x64-based Systems ServicePack 1
1.3 漏洞编号
CVE-2018-8120
二、漏洞细节
2.1漏洞位置及形成原因
漏洞函数位于win32k.sys模块的SetImeInfoEx() 函数, 该函数在使用一个内核对象的字段之前并没有进行是否为空的判断,当该值为空时,函数直接读取零地址内存。如果在当前进程环境中没有映射零页面,该函数将触发页面错误异常,导致系统蓝屏发生。
以下是漏洞产生位置的反汇编代码
可以看到,漏洞所在函数SetImeInfoEx()接收2个参数,漏洞的产生和参数1的结构体指针有关,下面跟踪一下参数1的来源。win32k!NtUserSetImeInfoEx() 系统服务函数调用了SetImeInfoEx()
_GetProcessWindowStation()返回当前进程的WindowStation内核对象, 当做参数1调用SetImeInfoEx()。以下是WindowStation内核对象的内存结构
程序可以通过系统提供的接口CreateWindowStation()和SetProcessWindowStation(),新建一个新的WindowStation对象并和当前进程关联起来,值得注意的是,使用CreateWindowStation() 新建的WindowStation对象其偏移0×14位置的spklList字段的值默认是零。
根据SetImeInfoEx()函数的流程,当WindowStation->spklList字段为0,函数继续执行将触发0地址访问异常。
2.2漏洞触发验证
前文已经介绍了漏洞所在位置,下面编写漏洞测试代码,测试该漏洞是否能够触发系统蓝屏。
NtUserSetImeInfoEx()系统服务函数未导出,需要自己在用户进程中调用该系统服务函数,以执行漏洞函数SetImeInfoEx()。
其中SyscallIndex的计算,根据系统ShadowSSDT表导出序号计算。
编译生成poc,开始执行
系统蓝屏,可以发现错误产生位置为0xBF91B399,下面在IDA中查看对应地址的指令,正是前文指出的SetImeInfoEx()中针对pWindowStation->spklList字段进行内存访问的代码。
三、漏洞利用
3.1漏洞利用之任意代码执行
由于SetImeInfoEx()没有正确的处理内存中的空指针对象, 普通应用程序可利用该漏洞以系统权限执行任意代码,下面将详细介绍如何在该漏洞现场实现任意代码执行。