2018年9月,Zero Day Initiative发布了微软Jet Database Engine漏洞CVE-2018-8423的PoC,并于2018年10月发布了补丁。研究人员在分析该漏洞和补丁时发现该漏洞的补丁会引发另一个漏洞CVE-2019-0576。
该漏洞利用了许多微软应用中都使用的Jet Database Engine的漏洞,其中就包括Access。攻击者利用该漏洞可以执行代码来进行权限提升或下载恶意软件。无从得知该漏洞是否已经被用于攻击活动中,但是PoC代码是随处可见的。

概览

为了利用该漏洞,攻击者需要利用社工技术使受害者打开一个JS文件,该JS文件使用ADODB connection对象来访问恶意Jet数据库文件。一旦访问恶意Jet数据库文件,就会调用msrd3x40.dll中有漏洞的函数,最终导致该漏洞被成功利用。

虽然PoC是导致wscript.exe奔溃,但实际上所有使用该DLL的应用都可能会受到该攻击的影响。
下面的错误信息表明该漏洞会被成功触发:

该消息表明在有漏洞的DLL中引发了访问违反。该漏洞是一个越界写漏洞,可以通过OLE DB触发,该API是许多微软应用中用来访问数据。该类漏洞表明数据可以在目标缓冲区外写数据导致奔溃。奔溃的原因是由于恶意伪造的JET数据库文件。利用Jet数据库文件格式的index域的文件有一个非常大的数,会导致越界写,最终引发前面提到的奔溃。

下图介绍了该漏洞利用的过程:

漏洞利用

PoC代码中含有一个JS文件(poc.js),会调用第二个文件(group 1)。这是一个Jet数据库文件。通过wscript.exe运行poc.js就会触发该奔溃。

从图中可以看出,引发该函数奔溃的是msrd3x40!TblPage::CreateIndexes。还可以确定该程序在尝试写数据,但是失败了。该程序用esi寄存器来在位置[edx+ecx*4+574h]处写,但该位置是无法访问的。

Debug信息表明寄存器ecx中含有值0x00002300Edx是一个指向内存的指针。最后,将这些和offset 0x574添加到一起来引用内存位置。根据这些信息可以猜测这里保存的数据类型。应该是一个数组,每个变量是4字节长,从位置edx+574h处开始。在追踪给程序时,研究人员确定了值0x00002300是来自于poc文件group 1

从上面我们了解到该程序会尝试越界写,并且确定了越界写发生的位置。下面分析为什么程序会尝试在该位置写。再此之前,需要了解Jet数据库,并根据用户提供的0x00002300处的数据来进行分析。

分析Jet数据库文件

许多研究人员都分析过Jet数据库文件结构。其中包括:

总结一下就是,Jet数据库文件是以页的形式组织,如下所示:

header page含有与文件相关的不同信息:

Header之后是含有key 0x6b39dac7的RC4加密的126字节,其中key对每个JetDB文件都是一样的。与PoC文件key值对比,可以发现group 1是Jet Version 3文件。

更多页pages定义参见http://jabakobob.net/mdb/table-page.html。

Table的定义数据有不同的域,其中包括Index CountReal Index Count

可以确定PoC文件中的这些值。检查group 1文件研究人员发现:

Index Count中一共有2个index。分析这个index研究人员值是很熟悉的0x00002300

0x00230000是table中index2index值。Index看似非常大,而且与crash有关。
为什么会使程序奔溃呢?通过分析文件,研究人员发现了两个index的名:

Debug

通过debugger,研究人员发现第一个程序调用了函数msrd3x40!operator new。这会为在eax中存储内存指针地址来分配内存:

内存分配后,程序会创建一个新的index:

该index值用于后面的执行过程。函数msrd3x40!Index::Restore会复制该index数到index地址+24h。这一过程会在所对所有index循环。首先调用分配内存的new,然后在该地址上创建一个index,并将index数一道index的基地址+24h。可以从下面的代码中看到移动的操作,表明恶意index值被复制到新创建的index中:

成功移动后,函数msrd3x40!NamedObject::Rename会被调用并复制index name值到index地址+40h

查看esi寄存器可以看到它指向index的地址。Ecx寄存器的值为[esi+24h],这也就是index数:

在一些指令操作后,可以看到引发奔溃的指令。Edx指向内存地址,ecx中含有来自文件group 1的非常大的数。该程序尝试访问[edx+ecx*4+574h]处的内存,这会引发越界写和程序奔溃:

程序要写的数据会引发什么呢?通过分析指令,可以看出程序尝试将esi中的值写入[edx+ecx*4+574],打印esi或前面的值,可以看到其中含有group 1中出现过的index name ParentIdName

最后,程序在尝试用很大的index数处理ParentIDName时就会奔溃。逻辑是:

  • 分配内存并获取内存开始位置的指针。
  • 内存位置+674h开始,程序会用文件中提到的index数乘4来保存指向index name的指针。

如果index数很大,又没有有效性验证,程序就会尝试越界写,并奔溃。

结论

这是一个逻辑错误,而此类错误一般很难发现。许多开发者都会采取额外的预防措施来避免代码中出现类似bug。如果出现了类似的问题,研究人员建议尽快应用厂商提供的补丁。

微软提供的补丁参见:
CVE-2018-8423
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8423
CVE-2019-0576
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0576

参考:
https://github.com/brianb/mdbtools/blob/master/HACKING
http://jabakobob.net/mdb/table-page.html


本文翻译自:https://securingtomorrow.mcafee.com/other-blogs/mcafee-labs/jet-database-engine-flaw-may-lead-to-exploitation-analyzing-cve-2018-8423/

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖