思科Talos公司在周四披露了Sophos HitmanPro.Alert中的两个漏洞,而今要在此展示这些漏洞所涉及的一系列利用的过程。这里我们深入探讨一下TALOS-2018-0636 / CVE-2018-3971漏洞的详细利用过程。
Sophos HitmanPro.Alert是一种基于启发式算法的威胁防护方案,它可检测并阻止恶意攻击的发生。 其中一些算法需要内核级访问来进行使用。 该软件的核心功能已由Sophos在hmpalert.sys
内核驱动程序实现。 此博客将记录攻击者如何利用TALOS-2018-0636构建稳定的漏洞来获取本地计算机上的SYSTEM权限。
在我们的研究过程中,我们在hmpalert.sys
驱动程序的IO控制处理程序中发现了两个漏洞。 在本文中,我们将仅关注TALOS-2018-0636 / CVE-2018-3971
。这些漏洞是Sophos HitmanPro.Alert
中特权漏洞的升级版本。 首先,我们将把它变成一个可靠的write-what-where漏洞,然后将其转变为完全可用。
首先,我们使用OSR Device Tree
工具(图1)来分析hmpalert.sys
驱动程序的访问权限。
我们可以看到成功登录到系统的用户都可以获得hmpalert
设备的处理程序并可以向其发送I / O请求。 正如我们在原始漏洞博客文章中提到的,与此漏洞相关的I / O处理程序由IOCTL代码“0x2222CC”触发。易受攻击的代码如下。
在实验中我们完全控制了这个函数的前三个参数,但是我们不能完全控制源数据(例如srcAddress
需要指向与lsass.exe进程相关的一些内存区域)(第12行)。
此外,从lsass.exe进程(第23行)读取的数据将复制到dstAddress
参数所指向的目标地址(第33行)。
有了这些基本信息,我们就可以构建第一个脚本来触发漏洞:
上图中看起来十分有效,但它还不足以创建一个有效的漏洞。 我们需要深入研究inLsassRegions
函数。下面我们看看如何测试srcAddress
参数。 我们必须检查我们是否能够预测这个内存内容,并将我们有限的“任意代码”访问转变为一个完全可用的“write-what-where”漏洞。
为了获取有关srcAddress
参数的更多信息,我们需要深入了解inLsassRegions
函数:
我们可以看到memoryRegionsList
列表元素有一个迭代过程,它由memRegion
结构表示。 memRegion
结构非常简单 - 它包含一个指向区域开头的字段和一个区域大小的字段。 srcAddress
值需要适配memoryRegionsList
元素边界。 如果满足了上述情况,函数就会返回“true”并复制数据。
即使只有srcAddress
值满足了边界条件(第21行),该函数也将返回'true'。 如果srcSize
值大于可用的空间,则将会更新srcSize
变量。问题是:这些内存区域代表了什么? initMemoryRegionList
函数将给我们一些帮助。
我们可以看到当前线程的上下文切换到lsass.exe
进程地址空间,然后调用createLsaRegionList
函数:
现在我们可以看到内存区域列表中已经填充了lsass.exe
PEB结构中的元素。 目前为止,列表中已经加载成功了映射的DLL的ImageBase地址,其中包括SizeOfImage(第31行)以及其他信息。 不幸的是,Lsass.exe
进程将作为服务运行, 这意味着攻击者具有正常的用户访问权限,我们将无法读取其PEB结构,但我们可以通过以下方式利用漏洞中DLL内容:像ntdll.dll
这样的系统DLL被映射到同一地址下进行处理,因此我们可以将lsass.exe
进程内存区域中的字节从这些系统DLL复制到dstAddress
参数指向的内存位置。 考虑到这一点,我们可以进行漏洞的利用。
这种漏洞不像我们平常在开发培训课程中看到的那样“写入地点”出错而产生的漏洞。也就是说我们很难找到这种漏洞并利用它。而这种漏洞研究过程是基于Morten Schenk在2017年BlackHat美国大会上的演讲中所提到的。Mateusz j00ru Jurczyk在他的论文中提出“利用Windows 10 PagedPool逐个溢出(WCTF 2018)”提出了修改方案。所以通过一部分的修改工作,我们可以使用j00ru的代码WCTF_2018_searchme_exploit.cpp
作为我们漏洞利用的模板。 包括:
1 删除与feng-shui相关的整个代码。
2 使用hmpalert.sys驱动程序中的原语为内存操作编写一个类。
3 根据ntoskrnl.exe和win32kbase.sys版本更新漏洞利用偏移量。
然后,我们使用Morten和Mateusz提到的策略:
1 我们假设我们的用户在“中等IL”级别运行,那么就要使用NtQuerySystemInformation API
泄漏出某些内核模块的地址。
2 使用地址nt!ExAllocatePoolWithTag
覆盖NtGdiDdDDIGetContextSchedulingPriority
中的函数指针。
3 使用NonPagedPool
参数调用NtGdiDdDDIGetContextSchedulingPriority
(= ExAllocatePoolWithTag
)来分配可写/可执行内存。
4 将ring-0 shellcode写入分配的内存缓冲区。
5 使用shellcode的地址覆盖NtGdiDdDDIGetContextSchedulingPriority
中的函数指针。
6 调用NtGdiDdDDIGetContextSchedulingPriority
(= shellcode
)。
将安全的TOKEN从系统进程复制到我们的进程后,shellcode会将我们的权限升级为SYSTEM访问权限。
在Windows上测试:Build 17134.rs4_release.180410-1804 x64 Windows 10
易受攻击的产品:Sophos HitmanAlert.Pro 3.7.8 build 750
为了简化内存操作,我们使用hmpalert.sys驱动程序为内存操作原语编写了一个类。
核心copy_mem
方法实现如下:
我们在类构造函数中初始化了几个重要元素:
我们可以使用write_mem
方法将特定值写入特定地址:
然而我们不能直接复制data
参数中定义的字节。 因此,我们需要从ntdll.dll
映射出的data
参数中搜索每个字节,然后通过srcAddress
参数将字节的地址传递给hmpalert驱动程序。 这样,我们就可以逐字节的使用data
参数中定义的字节覆盖目标地址dstAddress
处的数据。 我们可以轻松覆盖必要的内核指针,并使用此类将我们的shellcode复制到分配的页面:
其余的漏洞利用很简单,因此感兴趣的读者可以自行复现。
对于这个可利用的漏洞,我们对其进行了测试。如果它能够正常工作,那么我们会获得到SYSTEM级别权限。
看起来我们的漏洞被“HitmanAlert.Pro”的反零日检测引擎检测到了。 查看漏洞利用日志,我们发现它的整个代码都已执行,但生成的提升控制台却被终止。
我们可以在系统事件日志中看到HitmanAlert.Pro记录了一次利用这种方法进行本地提权的测试:
目前我们知道我们的漏洞利用可以正常进行,但是当权限进行提高时就会被检测引擎强制终止。
我们可以研究HitmanAlert.Pro的引擎并找出这个函数的具体实现位置。 Microsoft Windows API提供了“PsSetCreateProcessNotifyRoutine
”-可用于监视OS中的进程创建。 在hmpalert.sys
驱动程序中搜索此API调用,IDA显示了几个调用。
我们确实看到了一些注册回调的地方。 让我们看一下ProcessNotifyRoutine
的实现。 单独执行它时,我们发现了以下代码:
在第44行,我们看到了查杀此恶意程序的实例调用过程。正如我们在第5行所看到的,有一个条件检查是否设置了全局变量dword_FFFFF807A4FA0FA4
。 如果未设置,则不会执行其余的功能代码。 我们需要做的就是用零值覆盖这个全局变量的值,以避免控制台被终止调用的情况发生。漏洞的最后部分如下所示:
由于当今操作系统中的许多反开发功能,使用漏洞进行攻击的过程变的异常艰辛,但是这个特殊的漏洞表明我们仍然可以使用一些Windows内核级漏洞来轻松进行攻击。 本文深入探讨了攻击者如何发现此漏洞并将进一步利用进行攻击的过程。Talos将持续跟进此事件,并进行详细的分析。在本文中你可以查看原始的漏洞分析,并了解如何操作使自己的系统免收侵害。
本文为翻译稿件,翻译来自:https://blog.talosintelligence.com/2018/11/TALOS-2018-0636.html