CVE-2019-0576:CVE-2018-8423补丁绕过问题分析
2019-08-31 11:36:30 Author: www.4hou.com(查看原文) 阅读量:137 收藏

简介

2019年7月,微软修复了Jet Database Engine(Jet数据库引擎)中的43个bug,其中10个拥有CVE编号。之前研究人员分析了CVE-2018-8423漏洞产生的根源,在分析该漏洞的补丁时,研究人员发现有一种绕过该漏洞的方法,研究人员将该漏洞报告给微软,微软于2019年1月的补丁中修复了该来的,该漏洞CVE编号为CVE-2019-0576。研究人员建议用户更新系统到最新版本。

本文将介绍CVE-2019-0576漏洞的根源。为利用该漏洞,攻击者需要使用社会工程技术使受害者打开一个JS文件,JS文件会使用ADODB连接对象来访问恶意Jet数据库文件。一旦恶意Jet数据库文件被访问,就会在msrd3x40.dll中调用有漏洞的函数,导致该漏洞被利用。

背景

研究人员在之前的文章https://securingtomorrow.mcafee.com/other-blogs/mcafee-labs/jet-database-engine-flaw-may-lead-to-exploitation-analyzing-cve-2018-8423/中分析了如何使用恶意Jet数据库文件来触发CVE-2018-8423漏洞。如果index number太大,程序就会在以下位置奔溃:

ecx含有恶意index number。应用了微软CVE-2018-8423补丁后可以看到,打开恶意文件后,就会产生错误,而且奔溃不会再出现:

补丁分析

研究人员决定进一步分析该问题是如何打补丁的。分析msrd3x40!TblPage::CreateIndexes函数后,研究人员发现会检查IndexNumber是否大于0xFF(十进制的256),如下所示:

ecx中含有恶意值为00002300的index值,而且是大于0xFF。分析代码,研究人员发现其中有一个jump指令。如果查看jump指令,就可以看到以下位置:

可以看到其中调用了msrd3x40!Err::SetError函数,也就是说如果index值大于0xFF,恶意文件就不会被分析,程序就会给出错误消息Unrecognized database format并终止。

补丁中的问题

分析该补丁,可以看出如果index值大于0xFF,程序就会中止。研究人员准备用index值“00 00 00 20”测试一下,发现函数msrd3x40!Table::FindIndexFromName中发生了奔溃,如下所示:

问题根源

我们知道如果index值小于0xFF,函数msrd3x40!Table::FindIndexFromName就会奔溃,进一步分析发现奔溃发生在以下位置:

看起来好像程序尝试访问位置[ebx+eax*4+574h],但是不可访问,也就是说发生了越界读问题。

这里的奔溃与CVE-2018-8423中的非常相似,只不过CVE-2018-8423中的是越界写。查看eax发现其中含有0055b7a8,给它乘以4,就变成了一个非常大的数。

查看文件:

从下图可以看出,值00 00 00 20对应的index名为ParentIDName:

分析奔溃点的调试器,可以看出ebx+574h指向的是一个内存位置,eax含有乘以4的index值。下面计算:

1. 引发奔溃的eax值是什么?目前已经知道应该小于0xFF,但是最小值是多少呢?

2. 引发该漏洞的根本原因是什么?

在msrd3x40!Table::FindIndexFromName处设置断点,修改index值为0000001f,可以看出edx中含有指向index name为ParentIdName的指针:

继续调试发现来自[ebp]的eax值和来自[ebx+5F4h]的ebp值,如下所示:

ebx+5F4如下所示:

可以看出ebx+5F4含有文件中的所有index的index number。本例的文件中含有两个index,分别是“00 00 00 01”和“00 00 00 1f”。仔细检查内存可以看到index的最大值为0x20,也就是32:

开始位置为: 00718d54

每个index值为4字节,所以0x20*4 + 00718d54 = 00718DD4

然后查看ebx+574+4,可以看到其中含有指向index name的指针:

因此,完整的内存结构应该是这样的:

在位置EBX+574处只有0x80(128)字节来保持index name指针。每个指针都保持在index number位置,比如index number 1会保存在EBX+574+1*4,index number 2会保存在EBX+574+2*4,以此类推。

如果给定的index值大于31,程序就会覆写之前0x80字节的数据,是从位置EBX+5F4开始的,也是恶意文件的index number。本例中,如果用00 00 00 20替换00 00 00 1f,EBX+5F4位置处的index number就会被覆写,如下所示:

程序尝试在msrd3x40!Table::FindIndexFromName中执行该指令:

Mov ecx, dword ptr [ebx+eax*4+574h]

eax中含有的index number应该是00 00 00 01,但它被内存地址0055b7a8覆写了,该内存地址乘以4,就变成了一个大数,然后加上574h。如果内存区域中不存在,程序尝试从内存中读取,就出现了访问违规错误。

所以,前面的问题就有了答案:

1. 小于0xFF大于 0x31 会造成奔溃,如果来自[ebx+eax*4+574h]的内存位置不可访问。

2. 漏洞的根源在于index number被内存位置覆写了,引发无效的内存访问。

微软如何修复?

研究人员决定继续分析微软发布的补丁以了解是如何修复该漏洞的。从分析中可以看出,大于0x20(32)的值会引发奔溃,所以补丁就对此进行检查。微软在补丁中加入了该检查,如下所示:

如上图所示,eax中含有index值,并与0x20进行对比。如果大于或等于0x20,程序就会跳转到72fe1c00。分析该位置,可以看到:

如上图所示,它调用了destructor,然后调用了msrd3x40!Err::SetError函数。程序会显示消息Unrecognized database format,然后终止。

结论

研究人员于2018年10月将该漏洞报告给了微软,微软于2019年1月修复了该来的。漏洞CVE编号为CVE-2019-0576,研究人员建议用户更新Windows到最新版本,并及时安装厂商补丁。

本文翻译自:https://securingtomorrow.mcafee.com/other-blogs/mcafee-labs/analyzing-and-identifying-issues-with-the-microsoft-patch-for-cve-2018-8423/如若转载,请注明原文地址: https://www.4hou.com/vulnerable/20027.html


文章来源: https://www.4hou.com/vulnerable/20027.html
如有侵权请联系:admin#unsafe.sh