October 8, 2012

Flash Player Enables Sandbox via Global Pointer

The Windows version of Adobe Flash Player in Firefox has protected mode functionality. The concept of this mode is similar to the sandbox concept in Chrome: there is a broker process and a renderer process. The renderer process is running in low-integrity mode, and communicating with the broker process. The broker process is to give permission for legitimate system change but to reject questionable request made by the renderer process. The basic idea is the flash file is loaded and executed by the renderer process so, any non-legitimate invocation occurs by a vulnerability it will be rejected by the broker process.

Possible ways to circumvent the protection provided by protected mode include the followings. Corrupt the borkerer process to accept non-legitimate request from the renderer process. Or find Windows vulnerability to escalate right in low-integrity (i.e. renderer) process. Since the previous implementation when we didn't have the protected mode functionality is still available in the Flash Player it sounds to be logical by the attacker to disable protected mode functionality so the flash file is loaded and executed without sandbox protection. I'm exploring the latter further.

I examined NPSWF32_11_4_402_278.dll (11,264,432 bytes) file that is used in Firefox. In my test environment the DLL was located in C:\Windows\SysWOW64\Macromed\Flash folder. This file has the logic to decide if the flash file should be loaded and executed with or without sandbox protection. Flash Player uses a global pointer variable at fixed address (RVA: 0a2be70h) to store if sandbox mode should be used (1/0: with/without sandbox).

The value via the global pointer set to 1 by default (sandbox enabled) but it can be overwritten by adding ProtectedMode = 0 line to mms.cfg file that is located in the folder mentioned above.

Both the value and the page of the global pointer have the memory protection flags of read and write and since the global pointer is at a fixed address it's possible to overwrite it without changing memory protection flags or guessing the address.

Even though there is a need for a vulnerability to overwrite the global pointer table from security point of view it would be logical to discard the fixed address method and the writable memory protection flag. Using random address with read only page (apply writable flag when it's needed) would be more appropriate.

Here come some research artifacts.

Hijacking global pointer in Windbg. Higlighted dword is our new protected mode flag that is disabled.
0:000> sxe ld:NPSWF32_11_4_402_278
0:000> g
ModLoad: 59fe0000 5abbb000   C:\Windows\SysWOW64\Macromed\Flash\NPSWF32_11_4_402_278.dll
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=fffdd000 edi=0059bfcc
eip=7784fc42 esp=0059bea0 ebp=0059bef4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!NtMapViewOfSection+0x12:
7784fc42 83c404          add     esp,4
0:000> db 59fe0000 +a2be70
5aa0be70  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
5aa0be80  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
5aa0be90  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
5aa0bea0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
5aa0beb0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
5aa0bec0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
5aa0bed0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
5aa0bee0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0:000> .dvalloc 1000
Allocated 1000 bytes starting at 00730000
0:000> db 00730000
00730000  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00730010  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00730020  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00730030  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00730040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00730050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00730060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00730070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0:000> ed 59fe0000 +a2be70 00730000
0:000> g
Setting up protected mode flag below.
56245e56 807dff00        cmp     byte ptr [ebp-1],0
56245e5a 7406            je      NPSWF32_11_4_402_278!NP_SetNPAPIHostProxy+0x168c (56245e62)
56245e5c 8b45f8          mov     eax,dword ptr [ebp-8]
56245e5f c60001          mov     byte ptr [eax],1
56245e62 8bcb            mov     ecx,ebx
Checking if protected mode flag is set below.
56245e6f 8b75f8          mov     esi,dword ptr [ebp-8]
56245e72 59              pop     ecx
56245e73 803e00          cmp     byte ptr [esi],0
56245e76 0f8411010000    je      NPSWF32_11_4_402_278!NP_SetNPAPIHostProxy+0x17b7 (56245f8d) [br=1]
Highlighted code path of initialization with protected mode disabled below.
562460b0 e8dffeffff      call    NPSWF32_11_4_402_278!NP_SetNPAPIHostProxy+0x17be (56245f94)
562460b5 84c0            test    al,al
562460b7 7414            je      NPSWF32_11_4_402_278!NP_Initialize+0x57 (562460cd) [br=1]
562460b9 56              push    esi
562460ba e83bf4ffff      call    NPSWF32_11_4_402_278!NP_SetNPAPIHostProxy+0xd24 (562454fa)
562460bf 59              pop     ecx
562460c0 84c0            test    al,al
562460c2 7404            je      NPSWF32_11_4_402_278!NP_Initialize+0x52 (562460c8)
562460c4 33c0            xor     eax,eax
562460c6 eb0a            jmp     NPSWF32_11_4_402_278!NP_Initialize+0x5c (562460d2)
562460c8 33c0            xor     eax,eax
562460ca 40              inc     eax
562460cb eb05            jmp     NPSWF32_11_4_402_278!NP_Initialize+0x5c (562460d2)
562460cd e83595ffff      call    NPSWF32_11_4_402_278!unuse_netscape_plugin_Plugin+0x11de9 (5623f607)
562460d2 5e              pop     esi
562460d3 c20400          ret     4
I'd like to make it clear this is not a software vulnerability.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.