Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

2019-01-17 19:42:417303人阅读

2018年9月,FortiGuard实验室研究员Honggang Ren在Windows JET引擎Msrd3x40中发现了一个代码执行漏洞,并遵循Fortinet的负责披露流程向微软报告。2019年1月的星期二,Microsoft发布了一个安全公告,其中包含此漏洞的补丁,并将其标识为CVE-2019-0538

存在漏洞的DLL msrd3x40是所有受支持Windows版本的组件,从Windows 7到Windows 10。我们报告的漏洞可以使用精心设计的mdb文件触发。解析mdb PoC文件时,由于释放无效的堆地址而发生堆损坏。由此导致代码执行漏洞利用。

在本博客中,我们将分享对此漏洞的详细分析。

分析

有两种方法可以重现此漏洞。

方法1:

通过下面的参数使用Excel oledb外部数据源加载PoC文件,可以看到Excel崩溃。PoC文件可以位于本地或smb共享中。

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图1. 输入PoC.mdb 

方法2:

在Windows 10中,可以在命令窗口中执行“cscript.exe trigger.vbs”。

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图2. trigger1.vbs脚本

以下是崩溃发生时的调用堆栈。

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图3.发生崩溃时的调用堆栈

从上面的调用堆栈输出中,我们可以看到崩溃发生在函数“msrd3x40!free”中。让我们通过以下命令启用cscript.exe整页堆:“gflags / p / enable cscript.exe / full”。

然后,让我们检查堆内存地址中堆内存空闲失败的原因。内存处于MEM_RESERVE状态,如下所示:

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图4.free无效内存

通过逆向工程和跟踪,我们可以看到精心设计的mdb导致调用msrd3x40.dll出错,因为精心设计的mdb文件头版本字段为0。正常版本应为1。正常的mdb文件让程序进入header解密代码。但是,由于精心设计的mdb文件版本字段为0,精心设计的mdb文件没有在msjet40.dll中完成header解密。 

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图5.与精心制作的mdb版本进行比较并进入了错误的分支

因此,精心设计的mdb文件将导致进入函数msjet40!ErrOpenForeignDatabase + 0x65并调用msrd3x40.dll!ErrIsamOpenDatabase。但处理正常的mdb文件不会调用msrd3x40.dll。因此,精心设计的mdb文件导致它进入错误的代码分支。

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图6.调用msrd3x40.dll导致版本值错误

msrd3x40.dll解密精心设计的mdb header。偏移量0x42处的数据最初为0x86。在RC4解密mdb header之后,它使偏移量0x42处的数据变为0。因此采用另一个代码分支。请参阅以下代码:

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图7.比较msrd3x40.dll中解密的mdb header构造字节

到目前为止,仍然没有生成无效的堆内存地址。通过进一步的逆向工程和跟踪,我们发现用于生成无效堆内存的key因子来自以下代码:

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图8.key乘法因子变量在msrd3x40.dll中获得

运行上面的Database ::AssignUserNumber函数后,key乘法因子变量[esi + 6ch]等于0x100。

接下来,让我们跟踪无效的堆内存生成,如下所示:

Microsoft Windows JET引擎Msrd3x代码执行漏洞CVE-2019-0538分析

图9. msrd3x40.dll中生成的无效堆内存地址

在该函数中,[ecx +6c]是先前获得的密钥乘法因子0x100。这里,dx = 0x1。分配值后,[ecx + eax * 2 + 194h]实际分配给字1,其中这个字实际上是释放的无效存储器地址的低字。也就是说,在调用Database ::MarkCorrupt函数之前,目标对象堆指针是正确的。然而,在将值0x1字分配给上述存储器地址之后,生成无效堆指针。这导致释放无效指针和代码执行条件。

从上面的分析,我们可以看到漏洞的根本原因是格式错误的mdb版本值0x00,这导致程序采取错误的分支,并且精心设计的mdb文件偏移量0x42的数据为0x86,数据偏移量为0x600 -0x7ff 全等于0。这会导致使用0x100值创建乘法因子。在下一个函数调用中,由于乘法因子而导致目标堆地址的低位字被1覆盖,并且生成了无效的堆地址。释放无效堆地址时,会导致崩溃。成功利用此漏洞可能导致远程执行代码。

解决方案

鼓励Microsoft Windows Server存在漏洞版本的所有用户升级到最新的Windows版本。此外,已部署Fortinet IPS解决方案的机构自2018年10月12日起受到以下签名保护,不受此漏洞的影响:

MS.JET.Database.Engine.Msrd3x.Remote.Code.Execution

有关此0 day发现的更多详细信息,请参见此处(here)。


本文翻译自:https://www.fortinet.com/blog/threat-research/microsoft-windows-jet-engine-msrd3x-code-execution-vulnerability.html

翻译作者:TRex 原文地址:  http://www.4hou.com/vulnerable/15762.html

0
现金券
0
兑换券
立即领取
领取成功