CVE-2019-0576:CVE-2018-8423补丁绕过问题分析 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

CVE-2019-0576:CVE-2018-8423补丁绕过问题分析

ang010ela 漏洞 2019-08-31 10:36:30
171658
收藏

导语:研究人员对CVE-2018-8423补丁引发的安全漏洞进行了分析。

简介

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到最新版本,并及时安装厂商补丁。

  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务