起底CVE-2018-0825堆溢出缓冲区

微软最近发布了星期二的补丁,旨在修复一系列漏洞,其中14个漏洞被评估为关键漏洞。位列榜单之首的是CVE-2018-0825,这是在Windows动态库StructuredQuery.dll中的一个远程代码执行漏洞。据官方建议称,该漏洞影响了目前所有的微软Windows产品。由于这个漏洞还没有被公开揭露,应用及威胁情报(ATI)研究组决定深入探究一下状况,并观望一下微软事如何处理这种“即时修补”的漏洞。

环境和工具:

微软Win7x86 SP1被选为目标。此次任务将会用到以下工具:

  • Ida Pro 6.9 + Hex-Rays Decompiler on Fedora 25
  • Windows 10 x64 as debugging server
  • BinDiff plugin
  • WinDbg

注意:BinDiff官方并不支持Fedora,所以要将其与运行的Ida Pro整合,我们在官方配发的.deb包中得建立一个RPM包。

进行此项研究的大致步骤:

1.建立工作环境

2.获得两个版本的目标二进制(StructuredQuery.dll),未打补丁版本和打过补丁的版本

3.在Ida Pro中打开两个版本,为各自保存相应的.idb分析文件。

运行BinDiff的.idb文件,确定差别并找到漏洞

5.在未打补丁的微软Windows版本上对漏洞进行测试

详细步骤

1.建立工作环境

含Hex-Rays反编译器的Ida Pro 6.9在我们的Fedora 25机器上已经安装完成。BinDiff官方并不支持Fedora,所以安装完与Ida Pro进行整合,我们下载了Debian包并将其转化为RPM,然后在Fedora上面进行安装,使用以下说明(https://www.0x90.se/install-bindiff-in-fedora/)。

当Windows二进制在Linux系统的Ida Pro中分析时,反汇编器需要一个Windows调试服务器下载符号。功能名比晦涩难懂的标签或地址要简单得多。我们使用一个Windows10x64 box、IP与Fedora box相连接,运行win32_debugger.exe. Win32_debugger.exe是用Ida Pro(非免费版本)进行传送,故从Fedora上拷贝到Windows 10上运行。

2.获取两种版本的目标二进制

首先,对Windows 7×86 SP1目标窗口的升级状态进行检查。在安装升级的Windows中,上一次更新的安装时间为01/19/2018。微软在二月发布了补丁,所以这个窗口是选取漏洞库的好地方。

起底CVE-2018-0825堆溢出缓冲区

StructuredQuery.dll在%WINDIR%\System32里,故我们将其拷入Fedora窗口,在Ida Pro中进行分析。

对于库中的已修复版本,只需要进行简单操作:

a.从此漏洞的厂商知道页面中,找到具体Windows更新包,解决这个问题- KB4074587.

起底CVE-2018-0825堆溢出缓冲区

b.有了更新包ID后,我们就可以从微软更新目录中进行下载了(http://www.catalog.update.microsoft.com)

起底CVE-2018-0825堆溢出缓冲区

我们将文件命名为:

windows6.1-kb4074587-x86_4acde011f9386e8555109c8a06d406bbcee20a99.msu

可以进行扩展(Windows Vista), 使用工具:

expand –f:* windows6.1-kb4074587-x86_4acde011f9386e8555109c8a06d406bbcee20a99.msu C:\\expanded\\

该扩展工具在导出目录中生成了一堆文件和目录。搜索“StructuredQuery.dll”,会得出想要的结果:

起底CVE-2018-0825堆溢出缓冲区

看一下两个库文件的属性(旧的和扩展的),我们可以看到两个版本之间的差别,尽管文件大小相同:

起底CVE-2018-0825堆溢出缓冲区

将文件拷贝到Fedora box进行分析,第二步完成。

3.在Ida Pro中打开二进制

为进行差异分析,在由Ida Pro对二进制进行初始分析后,BinDiff需要二进制.idb文件结果。为更好进行追踪,我们将旧的二进制重新命名为StructuredQuery_unpatched.dll,新的二进制命名为structuredquery_patched.dll.

  1. a.打开Ida Pro里的structuredquery_patched.dll,让其在调试服务器中下载调试符号。在初始分析完成后,保存并关闭Ida Pro进程。
  2. 对StructuredQuery_unpatched.dll重复操作,但这次不要结束进程。

4.在.idb上运行BinDiff

在StructuredQuery_unpatched.dll的初始分析完成后,点击CTRL + 6启动BinDiff。

起底CVE-2018-0825堆溢出缓冲区

点击Diff Database并浏览之前保存的.idb文件。

在BinDiff分析完成后,我们得到以下结果:

起底CVE-2018-0825堆溢出缓冲区

查看的最好方法是通过相似性升序。这个案例里我们看到了这些StructuredQuery.dll版本的总共15种功能。该功能最大的不同是StructuredQuery1::ReadPWSTR(IStream*, ushort **),这为我们提供了一处CVE-2018-0825补丁所在之处的可能线索。下面列的是两种库中相同功能的伪代码版本,以Hex-Rays反编译:

起底CVE-2018-0825堆溢出缓冲区

总结一下ReadPWSTR()的内容:

a.从pstm (pointer to IStream)中读取4 bytes,并将值存储到pv

b.让CoTaskMemAlloc()分配大小为 2 * pv的内存缓冲区

c.如果分配成功,再次让IStream_Read()从pstm中再次读取(2 * pv -2) bytes,并存储到新分配的缓冲区。

现在来看一下差别。我们注意到新版本中的些许变化:

-pv变量是作为unsigned int,而不是int

-引进了新的局部变量SIZE_T cb

-用(2 * pv), &cb (note the inline casting of constant 2 to a unsigned integer64)启用了 ULongLongToULong()功能;MSDN(https://msdn.microsoft.com/is-is/library/windows/desktop/bb762429(v=vs.85).aspx)提供了该功能的细节

– cb变量作为参数传递给CoTaskMemAlloc(),而不是2 * pv

显而易见,这些变化是相关联的,补丁的目的是为验证pv值在被传递前作为CoTaskMemAlloc()的一个论据。

据MSDN所述,CoTaskMemAlloc()采用SIZE_T论据作为分配的内存块大小,单位是字节。IStream_Read()功能采用了ULONG论据,代表功能试图从输入流中读取数据字节的数量,并写入目的地缓冲区。在32-bit系统上,这两种都是4字节的长度。在未修补版本中,pv是signed int,数值等于0x80000000,会发生以下情况:

-(SIZE_T)(2 * pv) = 0 => CoTaskMemAlloc(0) 被召唤, 长度为0的缓冲区会被分配

-(ULONG)( 2 * pv – 2) = 0xfffffffe => IStream_Read(pstm, <dest_buffer>, 0xfffffffe) 被召唤,0xfffffffe的长度被写入 到长度为o 的缓冲区

此处细节引我们得出以下结论:未打补丁的StructuredQuery.dll版本中,有一个整数的溢出漏洞,可以引到缓冲区溢出,让攻击者在漏洞系统上运行任意代码。

这是我们在下一步中要测试的内容。

5.测试漏洞

为了这个测试,我们创建了一个概念验证(PoC)win32控制台程序(structured_query_tests.cpp)以及一个恶意输入文件(poc.dat)。源代码和内容截屏如下:

起底CVE-2018-0825堆溢出缓冲区

Structured_query_tests.cpp

起底CVE-2018-0825堆溢出缓冲区

PoC malicious input file

Structured_query_tests.cpp包含my_ReadPWSTR()功能,一个StructuredQuery.dll中未打补丁的ReadPWSTR()版本。

Poc.dat文件包含4个起始字节,由IStream_Read (line 31)首次召唤读取,并保存为pv变量,随后用于再次召唤IStream_Read,触发漏洞(留意小端字节顺序)。

在运行structured_query_tests.exe后,我们的猜想得到确认。以下是我们的WinDbg:

起底CVE-2018-0825堆溢出缓冲区

所以,再次从poc.dat文件中召唤IStream_Read() (line 37) read 0x80000000 bytes,并写入长度为0 的分配缓冲区中,过度写入后续内存块,得出一个堆缓冲区溢出。

结论和未来工作

这个漏洞被微软发布的Windows安全升级补丁标记为关键(CVE-2018-0825),类型为堆缓冲区溢出,是初始整数溢出。这是由于变量类型的不恰当使用造成的。堆缓冲区溢出漏洞可被利用,故而攻击者可能会在漏洞机器上通过确定合时的攻击向量,运行任意代码。在Win 10系统中运行进程中快速搜索,使用Process Explorer确定将近20种进程可撬动StructuredQuery.dll,包括但不限于:OUTLOOK.exe, EXCEL.exe, explorer.exe, chrome.exe。

原创文章,作者:M0tto1n,如若转载,请注明出处:http://www.mottoin.com/109250.html

发表评论

登录后才能评论

联系我们

021-62666911

在线咨询:点击这里给我发消息

邮件:root@mottoin.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code