The blog continues at suszter.com/ReversingOnWindows

Showing posts with label Flash Player. Show all posts
Showing posts with label Flash Player. Show all posts

August 9, 2014

Instrumenting Flash Player to Inspect JITted Pages for Integer Errors

In this blog post I'm writing about the method I experiment with to discover potential areas, that may or may not be prone to integer errors, in Flash Player.

I have 26k flash files that are used as a corpus to generate the test samples for Flash Player. The test samples have an element of 0x41424241 in the integer pool. I have a total of 344k files generated to test Flash Player with.

During the test, I use a pintool to instrument the JITted code. The pintool is based on this implementation. Since the elements in the integer pool being dereferenced by action script it makes sense to restrict the instrumentation to JITted code.

I use instruction-level instrumentation that allows to check the register values at every single instruction being executed. If any of the general registers have the value of 0x41424241 and the instruction is referencing to that register, the instruction information along with general registers are logged.

The pintool pre-allocates the address of 0x41424241 so Flash Player won't use that memory address and so reducing the irrelevant lines in the log.

There is no need to wait for the test to finish to get partial results. A log file is generated for each test file rendered by Flash Player.

The size of log files are vary. Some are close to size 0 specially if the value above makes the code to fail early. There are many log files with size 4k. When the execution keeps going long the size is about 16k. If the value has to do something with a loop the log can reach 100k but that's rare.

Logs can be grouped and many can be thrown away as they don't contain instructions associated with vulnerabilities.

What I look for is like signed shift, addition, subtraction, or multiplication instructions. If the value is used in displacement with lea instruction that counts suspicious too.

Once an address in the log is chosen for closer inspection, I reproduce the log on isolation with an option to dump the JITted pages so I can manually analyze the surrounding area of that address in disassembler. Knowing the state information it's also possible to debug the code.

If results positive, certain level of automation can be added.

July 16, 2014

251 Potential NULL Pointer Dereferences in Flash Player

251 potential NULL pointer dereference issues have been identified in Flash Player 14 by pattern matching approach. The file examined is NPSWF32_14_0_0_145.dll (17,029,808 bytes).

The issues are classified as CWE-690: Unchecked Return Value to NULL Pointer Dereference.

I don't copy&paste all the issues in this blog post but bringing up few examples.

First Example

0:012> uf 5438a1d0
NPSWF32_14_0_0_145!BrokerMainW+0xf6f6b:
5438a1d0 f6410810        test    byte ptr [ecx+8],10h
5438a1d4 8b4104          mov     eax,dword ptr [ecx+4]
5438a1d7 7411            je      NPSWF32_14_0_0_145!BrokerMainW+0xf6f85 (5438a1ea)

NPSWF32_14_0_0_145!BrokerMainW+0xf6f74:
5438a1d9 85c0            test    eax,eax
5438a1db 740b            je      NPSWF32_14_0_0_145!BrokerMainW+0xf6f83 (5438a1e8)

NPSWF32_14_0_0_145!BrokerMainW+0xf6f78:
5438a1dd 8b4c2404        mov     ecx,dword ptr [esp+4]
5438a1e1 8b448808        mov     eax,dword ptr [eax+ecx*4+8]
5438a1e5 c20400          ret     4

NPSWF32_14_0_0_145!BrokerMainW+0xf6f83:
5438a1e8 33c0            xor     eax,eax <--Set return value to NULL

NPSWF32_14_0_0_145!BrokerMainW+0xf6f85:
5438a1ea c20400          ret     4 <--Return with NULL
0:012> u 5438a47b L2
NPSWF32_14_0_0_145!BrokerMainW+0xf7216:
5438a47b e850fdffff      call    NPSWF32_14_0_0_145!BrokerMainW+0xf6f6b (5438a1d0)
5438a480 8a580c          mov     bl,byte ptr [eax+0Ch] <--Dereference NULL 

Second Example

0:012> uf 54362e60
NPSWF32_14_0_0_145!BrokerMainW+0xcfbfb:
54362e60 8b4128          mov     eax,dword ptr [ecx+28h]
54362e63 8b4c2404        mov     ecx,dword ptr [esp+4]
54362e67 3b4804          cmp     ecx,dword ptr [eax+4]
54362e6a 7205            jb      NPSWF32_14_0_0_145!BrokerMainW+0xcfc0c (54362e71)

NPSWF32_14_0_0_145!BrokerMainW+0xcfc07:
54362e6c 33c0            xor     eax,eax <--Set return value to NULL
54362e6e c20400          ret     4 <--Return with NULL

NPSWF32_14_0_0_145!BrokerMainW+0xcfc0c:
54362e71 56              push    esi
54362e72 8b748808        mov     esi,dword ptr [eax+ecx*4+8]
54362e76 56              push    esi
54362e77 e8e4b0faff      call    NPSWF32_14_0_0_145!BrokerMainW+0x7acfb (5430df60)
54362e7c 83c404          add     esp,4
54362e7f 85c0            test    eax,eax
54362e81 7407            je      NPSWF32_14_0_0_145!BrokerMainW+0xcfc25 (54362e8a)

NPSWF32_14_0_0_145!BrokerMainW+0xcfc1e:
54362e83 8b4010          mov     eax,dword ptr [eax+10h]
54362e86 5e              pop     esi
54362e87 c20400          ret     4

NPSWF32_14_0_0_145!BrokerMainW+0xcfc25:
54362e8a 8bc6            mov     eax,esi
54362e8c 83e0f8          and     eax,0FFFFFFF8h
54362e8f 5e              pop     esi
54362e90 c20400          ret     4
0:012> u NPSWF32_14_0_0_145+006b4eb2 L2
NPSWF32_14_0_0_145!BrokerMainW+0xd1c4d:
54364eb2 e8a9dfffff      call    NPSWF32_14_0_0_145!BrokerMainW+0xcfbfb (54362e60)
54364eb7 8b7004          mov     esi,dword ptr [eax+4] <--Dereference NULL

Third Example

0:012> uf 5429979a
NPSWF32_14_0_0_145!BrokerMainW+0x6535:
5429979a 0fb74108        movzx   eax,word ptr [ecx+8]
5429979e 48              dec     eax
5429979f 48              dec     eax
542997a0 740c            je      NPSWF32_14_0_0_145!BrokerMainW+0x6549 (542997ae)

NPSWF32_14_0_0_145!BrokerMainW+0x653d:
542997a2 83e815          sub     eax,15h
542997a5 7403            je      NPSWF32_14_0_0_145!BrokerMainW+0x6545 (542997aa)

NPSWF32_14_0_0_145!BrokerMainW+0x6542:
542997a7 33c0            xor     eax,eax <--Set return value to NULL
542997a9 c3              ret <--Return with NULL

NPSWF32_14_0_0_145!BrokerMainW+0x6545:
542997aa 8d4110          lea     eax,[ecx+10h]
542997ad c3              ret

NPSWF32_14_0_0_145!BrokerMainW+0x6549:
542997ae 8d410c          lea     eax,[ecx+0Ch]
542997b1 c3              ret
0:012> u NPSWF32_14_0_0_145+005f3423 L2
NPSWF32_14_0_0_145!BrokerMainW+0x101be:
542a3423 e87263ffff      call    NPSWF32_14_0_0_145!BrokerMainW+0x6535 (5429979a)
542a3428 8038fe          cmp     byte ptr [eax],0FEh <--Dereference NULL

You can find a list of 251 potential NULL pointer dereferences in Flash Player here.

July 14, 2014

Issues with Flash Player & Firefox in Non-default Configurations

Few months ago I encountered a bug when a fuzzed flash file is being rendered by Flash Player in Firefox. This bug can be reached only in the non-default configuration described below so very unlikely you are affected by this bug.

To trigger the bug the flash player module has to be loaded into Firefox's virtual address space. And this can be achieved if Flash Player protected mode is disabled and Firefox plugin container process is disabled too.

The bug involves to dereference arbitrary memory address via a CALL instruction in the vtable dispatcher. Here you can see the bug in the exception state.

0:048> g
Implementation limit exceeded: attempting to allocate too-large object
error: out of memory
(170fc.16998): 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=00000000 ecx=0034f670 edx=00000000 esi=1600f2c8 edi=0000001c
eip=5996bd5f esp=0034f638 ebp=0034f668 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SysWOW64\Macromed\Flash\NPSWF32_14_0_0_145.dll - 
NPSWF32_14_0_0_145!unuse_netscape_plugin_Plugin+0x5c2:
5996bd5f 8b461c          mov     eax,dword ptr [esi+1Ch] ds:002b:1600f2e4=????????
0:000> u eip L10
NPSWF32_14_0_0_145!unuse_netscape_plugin_Plugin+0x5c2:
5996bd5f 8b461c          mov     eax,dword ptr [esi+1Ch] <--Read unmapped address
5996bd62 a801            test    al,1
5996bd64 7420            je      NPSWF32_14_0_0_145!unuse_netscape_plugin_Plugin+0x5e9 (5996bd86)
5996bd66 33d2            xor     edx,edx
5996bd68 39550c          cmp     dword ptr [ebp+0Ch],edx
5996bd6b 7519            jne     NPSWF32_14_0_0_145!unuse_netscape_plugin_Plugin+0x5e9 (5996bd86)
5996bd6d 8b4e04          mov     ecx,dword ptr [esi+4]
5996bd70 83e0fe          and     eax,0FFFFFFFEh
5996bd73 89461c          mov     dword ptr [esi+1Ch],eax
5996bd76 8b06            mov     eax,dword ptr [esi] <--Read unmapped address
5996bd78 51              push    ecx
5996bd79 8bce            mov     ecx,esi
5996bd7b 895604          mov     dword ptr [esi+4],edx
5996bd7e 895618          mov     dword ptr [esi+18h],edx
5996bd81 ff500c          call    dword ptr [eax+0Ch] <--Dereference arbitrary memory content
5996bd84 eb06            jmp     NPSWF32_14_0_0_145!unuse_netscape_plugin_Plugin+0x5ef (5996bd8c)

I had reported this bug to Adobe and they opened a case PSIRT-2707 on 14/April/2014 but so far Adobe didn't confirm whether or not it was able to reproduce the bug or the exception state reported.

Again, the bug doesn't affect the default configuration, and so very unlikely you're affected by this. However, users using Firefox with plugin-container disabled as well as Flash Player plugin with protected mode disabled are affected by this issue.

The original report is about Flash Player 13_0_0_182 and Firefox 28.0 but the testcase fails with Flash Player 14_0_0_145 and Firefox 30.0 (latest available till today).

These are the steps to reproduce the bug.
  • Edit mms.cfg to have ProtectedMode=0 to disable protected mode in Flash Player
  • Start cmd.exe and type "set MOZ_DISABLE_OOP_PLUGINS=1" to disable plugin-container in Firefox
These settings above required to get Flash Player plugin loaded in firefox.exe's address space.
  • Start Firefox from command prompt opened previously
  • Open fuzzed.swf in Firefox (drag n drop should work)
  • Attach firefox.exe process to Windbg when you notice that Firefox is hanging
  • Exception should occur in few second. If you see the out-of-memory error in the debugger log without exception you may restart the browser and try again.
The fuzzed flash file has the following changes compared to the template file. The value of the first item in the integer pool has been changed to a large value. TagLength of DoAbc tag and FileSize of the main header have been therefore updated to maintain the integrity of the flash file.

Drop me an email if you think you need the testcase.

February 19, 2014

Bug in Flash Player when processing PNG format

The Bug

The PNG file consists of a sequence of data structures called chunks. A chunk has a Length field that is a DWORD value. A specially crafted Length field can cause integer overflow in Flash Player leading to read out of the designated buffer. Here is the disassembly code snippet explaining the bug.

015344a0 e8f7feffff      call    FlashPlayer!WinMainSandboxed+0x1f1122 (0153439c) ;Read CHUNK.Length from attacker controlled buffer
015344a5 8bd8            mov     ebx,eax                                          ;CHUNK.Length = 0ffffffd3h
015344a7 6a04            push    4
015344a9 8d45fc          lea     eax,[ebp-4]
015344ac 50              push    eax
015344ad 8bce            mov     ecx,esi
015344bb e8dcfeffff      call    FlashPlayer!WinMainSandboxed+0x1f1122 (0153439c)
015344c0 8b4d08          mov     ecx,dword ptr [ebp+8]
015344c3 8901            mov     dword ptr [ecx],eax
015344c5 8b560c          mov     edx,dword ptr [esi+0Ch]                          ;Current Position in buffer = 29h
015344c8 8945fc          mov     dword ptr [ebp-4],eax
015344cb 8d441a04        lea     eax,[edx+ebx+4]                                  ;<-First integer overflow
                                                                                  ;TotalValue = Position + CHUNK.Length + 4
                                                                                  ;TotalValue = 29h + 0ffffffd3h + 4 = 0
015344cf 3b4610          cmp     eax,dword ptr [esi+10h]                          ;Compare TotalValue (0) to FileSize (3d0h)
015344d2 7351            jae     FlashPlayer!WinMainSandboxed+0x1f12ab (01534525) ;Unsigned evaluation. Jump is not taken
015344d4 57              push    edi
015344d5 6afc            push    0FFFFFFFCh
015344d7 58              pop     eax
015344d8 83cfff          or      edi,0FFFFFFFFh
015344db 3bd8            cmp     ebx,eax                                          ;Compare CHUNK.Length (0ffffffd3h) to hardcoded 0FFFFFFFCh
015344dd 7e26            jle     FlashPlayer!WinMainSandboxed+0x1f128b (01534505) ;Signed evaluation. Jump is taken.
[...]
01534505 8b4e14          mov     ecx,dword ptr [esi+14h]                          ;Set pointer to Buffer
01534508 03ca            add     ecx,edx                                          ;Set Current Position in Buffer
0153450a 03cb            add     ecx,ebx                                          ;<-Second integer overflow
                                                                                  ;Increment by CHUNK.Length leading to position out of the buffer backward
0153450c e88bfeffff      call    FlashPlayer!WinMainSandboxed+0x1f1122 (0153439c)
[...]
0153439c 0fb601          movzx   eax,byte ptr [ecx]                               ;<-Can read out of designated buffer
0153439f 0fb65101        movzx   edx,byte ptr [ecx+1]                             ;<-Can read out of designated buffer
015343a3 c1e008          shl     eax,8
015343a6 0bc2            or      eax,edx
015343a8 0fb65102        movzx   edx,byte ptr [ecx+2]                             ;<-Can read out of designated buffer
015343ac 0fb64903        movzx   ecx,byte ptr [ecx+3]                             ;<-Can read out of designated buffer
015343b0 c1e008          shl     eax,8
015343b3 0bc2            or      eax,edx
015343b5 c1e008          shl     eax,8
015343b8 0bc1            or      eax,ecx
015343ba c3              ret

State in the erroneous code path looks like below. The designated buffer containing the content of PNG file starts at 00e4c810 where the PNG signature is seen. Due to the bug the instruction reads the memory at 4 bytes minus the pointer to the buffer, at 00e4c80c. Note, the instruction doesn't cause access violation because the illegally accessed memory address is mapped.

0:000> t
eax=fffffffc ebx=ffffffd3 ecx=00e4c80c edx=00000029 esi=0019e134 edi=ffffffff
eip=0153439c esp=0019dbf4 ebp=0019dc08 iopl=0         nv up ei pl nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000207
FlashPlayer!WinMainSandboxed+0x1f1122:
0153439c 0fb601          movzx   eax,byte ptr [ecx]         ds:002b:00e4c80c=00
0:000> db ecx
00e4c80c  00 00 00 00 89 50 4e 47-0d 0a 1a 0a 00 00 00 0d  .....PNG........
00e4c81c  49 48 44 52 00 00 01 2c-00 00 01 2c 08 02 00 00  IHDR...,...,....
00e4c82c  00 f6 1f 19 22 ff ff ff-d3 49 44 41 54 78 9c ed  ...."....IDATx..
00e4c83c  d9 31 8a c3 40 14 44 c1-1e e3 fb 5f 59 8a 9d 09  .1..@.D...._Y...
00e4c84c  1c bc 40 55 6c b4 20 70-f2 68 98 7f b6 6b bb ce  ..@Ul. p.h...k..
00e4c85c  ef df b6 f3 e8 9f f3 ad-6f 7d fb e7 b7 9f 01 a9  ........o}......
00e4c86c  ef 4e fd 13 e0 dd 44 08-31 11 42 4c 84 10 13 21  .N....D.1.BL...!
00e4c87c  c4 bc 8e 42 cc 12 42 4c-84 10 13 21 c4 44 08 31  ...B..BL...!.D.1

Root Cause

Two incorrect sanity checks were identified.

Incorrect sanity check (015344cf) because it happens after the overflow (015344cb).
Incorrect sanity check (015344db) because signed comparison is performed on CHUNK.Length that is unsigned.

Severity

The technical severity of this bug is low because diverting execution flow is not possible. Further analysis suggests that address disclosure is not possible because the memory region can be accessed out of the designated buffer doesn't contain address.

Reproduction

Open Flash Player 12.0.0.38 (flashplayer_12_sa.exe has a size of 10,339,208) in Windbg. Then execute the following command.
0:006> bp flashplayer + 001f44a0 2
0:006> g
Open the PoC in Flash Player (send me an e-mail for a copy). Debugger breaks-in so you can step through the disassembly code and see the data-flow as explained above.

I'm aware there is a new version of Flash Player 12.0.0.44. I verified and it's affected by this bug, too.

UPDATE On 26th February an Adobe engineer confirmed via e-mail that he could reproduce the bug.

February 13, 2014

Data Flow Tracking in Flash Player: Undocumented Bytecodes and JIT

Undocumented Bytecodes

I did some analysis how the bytecodes in DoABC tag parsed, and compared the result against what I saw in the AVM2 documentation (May 2007). I found that Flash Player can parse certain bytecodes that are not mentioned in the documentation.

Bytecode Note Bytecode Note Bytecode Note Bytecode Note
0x00 RESERVED 0x40 newfunction 0x80 coerce 0xc0 increment_i
0x01 UNDOCUMENTED 0x41 call 0x81 UNDOCUMENTED 0xc1 decrement_i
0x02 nop 0x42 construct 0x82 coerce_a 0xc2 inclocal_i
0x03 throw 0x43 callmethod 0x83 UNDOCUMENTED 0xc3 declocal_i
0x04 getsuper 0x44 callstatic 0x84 UNDOCUMENTED 0xc4 negate_i
0x05 setsuper 0x45 callsuper 0x85 coerce_s 0xc5 add_i
0x06 dxns 0x46 callproperty 0x86 astype 0xc6 subtract_i
0x07 dxnslate 0x47 returnvoid 0x87 astypelate 0xc7 multiply_i
0x08 kill 0x48 returnvalue 0x88 UNDOCUMENTED 0xc8 RESERVED
0x09 label 0x49 constructsuper 0x89 UNDOCUMENTED 0xc9 RESERVED
0x0a RESERVED 0x4a constructprop 0x8a RESERVED 0xca RESERVED
0x0b RESERVED 0x4b RESERVED 0x8b RESERVED 0xcb RESERVED
0x0c ifnlt 0x4c callproplex 0x8c RESERVED 0xcc RESERVED
0x0d ifnle 0x4d RESERVED 0x8d RESERVED 0xcd RESERVED
0x0e ifngt 0x4e callsupervoid 0x8e RESERVED 0xce RESERVED
0x0f ifnge 0x4f callpropvoid 0x8f RESERVED 0xcf RESERVED
0x10 jump 0x50 UNDOCUMENTED 0x90 negate 0xd0 getlocal_0
0x11 iftrue 0x51 UNDOCUMENTED 0x91 increment 0xd1 getlocal_1
0x12 iffalse 0x52 UNDOCUMENTED 0x92 inclocal 0xd2 getlocal_2
0x13 ifeq 0x53 UNDOCUMENTED 0x93 decrement 0xd3 getlocal_3
0x14 ifne 0x54 RESERVED 0x94 declocal 0xd4 setlocal_0
0x15 iflt 0x55 newobject 0x95 typeof 0xd5 setlocal_1
0x16 ifle 0x56 newarray 0x96 not 0xd6 setlocal_2
0x17 ifgt 0x57 newactivation 0x97 bitnot 0xd7 setlocal_3
0x18 ifge 0x58 newclass 0x98 RESERVED 0xd8 RESERVED
0x19 ifstricteq 0x59 getdescendants 0x99 RESERVED 0xd9 RESERVED
0x1a ifstrictne 0x5a newcatch 0x9a RESERVED 0xda RESERVED
0x1b lookupswitch 0x5b RESERVED 0x9b RESERVED 0xdb RESERVED
0x1c pushwith 0x5c RESERVED 0x9c RESERVED 0xdc RESERVED
0x1d popscope 0x5d findpropstrict 0x9d RESERVED 0xdd RESERVED
0x1e nextname 0x5e findproperty 0x9e RESERVED 0xde RESERVED
0x1f hasnext 0x5f UNDOCUMENTED 0x9f RESERVED 0xdf RESERVED
0x20 pushnull 0x60 getlex 0xa0 add 0xe0 RESERVED
0x21 pushundefined 0x61 setproperty 0xa1 subtract 0xe1 RESERVED
0x22 RESERVED 0x62 getlocal 0xa2 multiply 0xe2 RESERVED
0x23 nextvalue 0x63 setlocal 0xa3 divide 0xe3 RESERVED
0x24 pushbyte 0x64 getglobalscope 0xa4 modulo 0xe4 RESERVED
0x25 pushshort 0x65 getscopeobject 0xa5 lshift 0xe5 RESERVED
0x26 pushtrue 0x66 getproperty 0xa6 rshift 0xe6 RESERVED
0x27 pushfalse 0x67 UNDOCUMENTED 0xa7 urshift 0xe7 RESERVED
0x28 pushnan 0x68 initproperty 0xa8 bitand 0xe8 RESERVED
0x29 pop 0x69 RESERVED 0xa9 bitor 0xe9 RESERVED
0x2a dup 0x6a deleteproperty 0xaa bitxor 0xea RESERVED
0x2b swap 0x6b RESERVED 0xab equals 0xeb RESERVED
0x2c pushstring 0x6c getslot 0xac strictequals 0xec RESERVED
0x2d pushint 0x6d setslot 0xad lessthan 0xed RESERVED
0x2e pushuint 0x6e getglobalslot 0xae lessequals 0xee RESERVED
0x2f pushdouble 0x6f setglobalslot 0xaf greaterequals 0xef debug
0x30 pushscope 0x70 convert_s 0xb0 UNDOCUMENTED 0xf0 debugline
0x31 pushnamespace 0x71 esc_xelem 0xb1 instanceof 0xf1 debugfile
0x32 hasnext2 0x72 esc_xattr 0xb2 istype 0xf2 UNDOCUMENTED
0x33 RESERVED 0x73 convert_i 0xb3 istypelate 0xf3 RESERVED
0x34 RESERVED 0x74 convert_u 0xb4 in 0xf4 RESERVED
0x35 UNDOCUMENTED 0x75 convert_d 0xb5 RESERVED 0xf5 RESERVED
0x36 UNDOCUMENTED 0x76 convert_b 0xb6 RESERVED 0xf6 RESERVED
0x37 UNDOCUMENTED 0x77 convert_o 0xb7 RESERVED 0xf7 RESERVED
0x38 UNDOCUMENTED 0x78 checkfilter 0xb8 RESERVED 0xf8 RESERVED
0x39 UNDOCUMENTED 0x79 RESERVED 0xb9 RESERVED 0xf9 RESERVED
0x3a UNDOCUMENTED 0x7a RESERVED 0xba RESERVED 0xfa RESERVED
0x3b UNDOCUMENTED 0x7b RESERVED 0xbb RESERVED 0xfb RESERVED
0x3c UNDOCUMENTED 0x7c RESERVED 0xbc RESERVED 0xfc RESERVED
0x3d UNDOCUMENTED 0x7d RESERVED 0xbd RESERVED 0xfd RESERVED
0x3e UNDOCUMENTED 0x7e RESERVED 0xbe RESERVED 0xfe RESERVED
0x3f RESERVED 0x7f RESERVED 0xbf RESERVED 0xff RESERVED

The loop and the big switch statement parsing DoABC bytecode is near 0x6087e9. Instruction near 0x58f25d also reads bytecode. The documentation certainly needs an update on Adobe's side so developers can add the currently undocumented bytecodes to their decompiler/disassembler.

JIT

After adding new functionalities to my pintool I run it against Flash Player. Here is my observation.

When executing a flash file containing DoAction tag in Flash Player no memory page allocated with or set to *EXECUTE* flag. Thus no dynamically generated code was executed with the most common method. Therefore I think DoAction works with interpreted execution. Meaning every single bytecode run on isolation rather than a set of bytes compiled&run (JIT).

When executing a flash file containing DoABC tag in Flash Player I observed increased usage of VirtualAlloc. The page was allocated with PAGE_READWRITE flag. Later on the execution the page was set to PAGE_EXECUTE_READ and the execution flow was transferred to the page. When the execution was returned to the caller the page was set back to PAGE_READWRITE. I knew this was a part of how JIT works. Change of the memory protection flags is the mitigation for DEP.

0x5205a6 is a VirtualProtect call to change the memory protection flags. When it's called with PAGE_READWRITE it's called via 0x5fc39c. When it's called with PAGE_EXECUTE_READ it's called via 0x5fc2e9.

During my experiment I figured out that instruction at 0x5d20ef calls into the JIT-compiled code. Though this might not be the only address to call JIT-compiled code from. I observed many call backs in the JIT-compiled code. One of the callback might be to give continuous feedback to the caller for example if a long loop is being executed. I observed that constants are encrypted with xor instructions to make memory spraying more difficult. This is not new but first time for me to see. This is how 0x41414141 looks like when it's encrypted.
03af1f67 b83a7c1959      mov     eax,59197C3Ah
03af1f6c 357b3d5818      xor     eax,18583D7Bh
All offsets in this post are RVAs, that is relative to Flash Player's image base. Offsets are appropriate in Flash Player 12.0.0.38 (flashplayer_12_sa.exe has a size of 10,339,208).

February 9, 2014

Data Flow Tracking in Flash Player: DefineBitsJPEG2

Here are some offsets of the standalone Flash Player 12.0.0.38 (flashplayer_12_sa.exe has a size of 10,339,208). The offsets are reached when parsing ImageData field in DefineBitsJPEG2 tag.
0x570e7  | Checks for PNG signature.
0x57124  | Checks for GIF87a signature.
0x57138  | Checks for GIF89a signature.
0x5717D  | Checks for JPEG XR (Windows Media Photo) signature.
0x5719B  | Checks for ATF (Adobe Texture Format) signature.
0x4b6fc2 | Checks for JPEG (ff d8) signature.
The first five checks performed on the permanent buffer that I wrote about in the previous post. The last check is performed on the match buffer that contains the first 0x200 bytes of ImageData in the permanent buffer. The bytes are copied from the permanent buffer to the match buffer using fast memcpy function (0x701030).

I looked at the specification of DefineBitsJPEG2 tag. It's interesting to see that swf specification version 19 says "Compressed image data is either JPEG, PNG, or GIF89a format". However as seen above there might be other file formats supported. Good to know if you want to fuzz this area.

All offsets in this post are RVAs, that is relative to Flash Player's image base.

February 4, 2014

Data Flow Tracking in Flash Player

I've been writing a Pintool that is to track the data flow between buffers in Flash Player. The tool logs when bytes from the flash file are read to the buffer, and when bytes from the buffer are copied to the subsequent buffer. The tool also logs the instruction that dereferences a position in the buffer. And, if appropriate, the tool can project the position in the buffer back to the position in the flash file.

Using Pintool can speed up the work that I would do with debuggers otherwise. When analyzing with Pintool I don't see all the non-relevant instructions that a debugger would show up but rather see more, and more relevant information. Therefore I can focus better on what's important.

I picked up an uncompressed flash file - with FWS signature in its header - and loaded it in the standalone Flash Player 12.0.0.38 (flashplayer_12_sa.exe).

When executing, the flash file is read by a loop of ReadFile() that takes 0x10000 as the number of bytes (64Kb) to read in each iteration. Once ReadFile() receives the bytes read from the file, the bytes are copied to the permanent buffer. _fastcopy_I is used to copy bytes to the permanent buffer that has RVA of 0x70c396. Note, it's reasonable to assume there might be other copy functions embedded in Flash Player for different architectures.

Many bytes in the permanent buffer are just propagated to other buffers. Otherwise, a validation is directly performed by dereferencing certain regions of the permanent buffer. I was looking at the latter as I'd inspect the data flow on a deeper level at a later date. One such validation on the permanent buffer is the following inline strlen() core, that has RVA of 0x1a922.

0040a922 8a08            mov     cl,byte ptr [eax]
0040a924 40              inc     eax
0040a925 84c9            test    cl,cl
0040a927 75f9            jne     FlashPlayer!WinMainSandboxed+0x176a8 (0040a922)


Instructions dereference the permanent buffer from 42 ditinct locations in Flash Player. I had a look at the addresses with their surrounding code and found the inline strlen() core above to be the most interesting. Note, the above inline strlen() core can be found at multiple locations in Flash Player.

There are couple of reasons I found the above code interesting. When looking at the surrounding code I didn't see sanity check of the string size. The position in the buffer can be projected back to the position in the flash file by Pintool. At this point, I suspected I had good control over the string size as I can make it to be a long string and even I can remove the ending zero in the flash file without causing Flash Player to bail out early.

Below is the screenshot of the flash file. strlen() is triggered on "movieLoader" string ending with zero. It's highlighted.

I was considering to alter the flash file in a way to overwrite the ending zero of the string, and all subsequent zeros in the following tags (DefineButton2, PlaceObject2, etc). It would mean the string would run until the end of the file hoping strlen() to read out of the bounds. Actually, when experimenting, I took the plunge to remove the last few tags and appended few "A" characters to the string until end-of-file, without ending zero. Also, adjusted the file size in the header as it was obligatory. Here is a photo of the string.

I run Flash Player and saw in the log produced by Pintool that the inline strlen() is triggered meaning it processes the altered string. This is good because the code is still reachable when reading the corrupted string. However an unexpected zero byte beyond the string causing the loop to break without Flash Player entering in an inconsistent state or reading out of bounds.

I wanted to know how the zero byte is set at the end of the string so I changed Pintool to log all write accesses on the permanent buffer. When I run Flash Player again, I didn't see in the log that zero byte is set at the end of the string. As being paranoid today, I immediately thought that might be an uninitialized value that is zero by chance but this was a guess so thought better check how the memory is allocated for the permanent buffer. I added the required code to Pintool to see how the memory is allocated and I saw it is allocated by VirtualAlloc. This explains the zero byte as memory allocated with this function is automatically initialized with zero.

I was thinking if I can construct the flash file to place the string at the end of memory page without leaving space for padding zero bytes. I was able to control the amount of memory to allocate by changing the file size field in the flash file (at offset 4). What I observed is that the size of allocated memory is always bigger than the file size in the header and so there are always padding bytes. In my experiment I saw the pattern that the amount of memory to be allocated is calculated by incrementing the file size by one and rounding up to the nearest multiple of 0x1000.

It seems defense against this string attack is consciously added by Adobe preventing to read out of bounds.

January 14, 2014

Flash Player Unloading Vulnerability III

This is the third article in this series that I didn't expect to write but it turns out the fix for CVE-2013-5332 insufficiently addresses the issue around the dialog boxes. Adobe had issued a fix that prevents the testcase I provided them from crashing the plugin but it's still possible to reach the bug just by adding an additional step to that testcase. I talked to Adobe about this.

Now the crash state is different to the crash state previously seen but in both cases the instruction dereferences freed memory. The vulnerability enables the attacker to divert the execution flow via the dispatch table that can be constructed due to a use-after-free issue.

I'm using Application Verifier and GFlags tool to make the vulnerability easy to see, and I'm also doing this because I observed that the application didn't crash at certain times. It could have happened because an object was allocated to the freed memory in a way to contain a valid function pointer. So rather than dereferencing freed memory the wrong function was called by the dispatcher and the execution completed without access violation.

Anyway here is the configuration. I configured GFlags for Internet Explorer 11 like below.

Configured Application Verifier, too.

In Windbg, I set debug of child process so when to open iexplore.exe from the disk I'm able to debug both broker and renderer processes. In the beginning of the article I mentioned that an additional step is required to the testcase in order to trigger the bug. It is to visit a web page that contains a Flash object which simply is to exercise the Flash plugin. After that, we can load the testcase to trigger the dialog box seen below.

At this point we can see many problems reported by Application Verifier. Here are two.
=======================================
VERIFIER STOP 00000202: pid 0xBE0: Freeing heap block containing an active critical section.

4C3D6FE0 : Critical section address.
00DEF2FC : Critical section initialization stack trace.
4C3D6FE0 : Heap block address.
0000001C : Heap block size.

=======================================
[...]
=======================================
VERIFIER STOP 00000350: pid 0xBE0: Unloading DLL that allocated TLS index that was not freed.

004BABBA : TLS index
6759965F : Address of the code that allocated this TLS index.
4B916FCE : DLL name address. Use du to dump it.
67060000 : DLL base address.

=======================================
After the close of dialog box the instruction at 6724f02b dereferences freed memory during processing the dispatch table. I highlighted the vulnerable path that can execute injected code.
(c44.e64): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\system32\Macromed\Flash\Flash32_11_9_900_170.ocx -
eax=0b611060 ebx=0b5fd0a0 ecx=7ffd7000 edx=6e1027a4 esi=0b5ef000 edi=0b612020
eip=6724f02b esp=067fc018 ebp=067fc028 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210206
Flash32_11_9_900_170!DllUnregisterServer+0x173da:
6724f02b 8b7024 mov esi,dword ptr [eax+24h] ds:0023:0b611084=????????
2:055> u
Flash32_11_9_900_170!DllUnregisterServer+0x173da:
6724f02b 8b7024 mov esi,dword ptr [eax+24h] <--Read freed memory
6724f02e eb02 jmp Flash32_11_9_900_170!DllUnregisterServer+0x173e1 (6724f032)
6724f030 33f6 xor esi,esi
6724f032 85f6 test esi,esi
6724f034 7420 je Flash32_11_9_900_170!DllUnregisterServer+0x17405 (6724f056)

6724f036 8b06 mov eax,dword ptr [esi] <--Read attacker controlled memory
6724f038 8bce mov ecx,esi
6724f03a ff5004 call dword ptr [eax+4] <--Divert execution
 I recorded a video of the vulnerability using the latest Flash Player (12.0.0.38) for Internet Explorer.

December 11, 2013

Flash Player Unloading Vulnerability II

UPDATED 20/February 2014: This vulnerability is CVE-2013-5332 and technical details were publicly announced on 10th December 2013 after the vendor patch was released to end users. On 19th of February 2014 I unexpectedly received an e-mail from HackerOne saying "The Internet Bug Bounty has awarded you a $2000.00 bounty for Flash memory corruption vulnerability could lead to code execution".

Adobe has notified me that it addressed the Flash Player Unloading vulnerability I reported them earlier. The patch is now released to end users and the security bulletin is published which contains the nature of the vulnerability.

In this post, I describe the technical details of the vulnerability in the hope that software developers can learn from it.

In the Windows version of Safari, when a Flash file is opened, the browser initiates to load the Flash Player into the process address space. When the Flash file is no longer opened the browser initiates to unload the Flash Player.

The Flash Player can display a dialog box using MessageBox API. While the dialog box is active, an other thread can unload the Flash Player module from the address space. When the execution returns back from the MessageBox call to the Flash Player module, which is already unloaded, the instruction dereferences freed memory causing data execution prevention exception.

This is a use-after-free vulnerability and it is same in nature to the one I reported Adobe earlier however this time the vulnerability is triggered via a different code path. The crash state looks like below, and it suggests the issue is most likely exploitable for code execution.
(3860.37ec): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=523bb781 ebx=00000001 ecx=006f0d68 edx=00000000 esi=523bb781 edi=00000000
eip=523bb781 esp=001deb90 ebp=001debb8 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210206
<Unloaded_NPSWF32_11_7_700_224.dll>+0x20b781:
523bb781 ??              ???
0:000> |.
.  0          id: 3860               attach    name: C:\Program Files (x86)\Safari\Apple Application Support\WebKit2WebProcess.exe
One possible fix would be to synchronize the DLL unloading thread with the code calling MessageBox.

The vulnerability I reported Adobe earlier is same in nature to this one. Also, if a developer purely adds a new MessageBox call he has a high probability to inherently create a new vulnerability that can be reached in the same way described in this post. Therefore, for Adobe, it would be beneficial to review the entire code base for unsafe dialog box calls.

Also, for Microsoft, hardening on OS level is worthy to consider which may involve to crash in a not exploitable manner when a bug is triggered. The problem looks to be more ubiquitous than the public vulnerability reports suggest. The approach to discover these issues is to identify dialog box and DLL unloading code fragments that can be manually attacked.

Since there may be many bugs that could end up dereferencing unloaded Flash Player, Mozilla long time back fixed the problem by permanently keeping the plugin in the memory in Firefox process.

I'm currently working on tools to identify attack surfaces. It involves to identify DLLs calling MessageBox, and identify ways to unload MessageBox DLLs from the process address space.

I created a sample implementation to represent the vulnerability including how the freed memory gets dereferenced. It is a good exercise for developers to think about how to make the code secure without removing the thread creation.
// This is the EXE file.
// Main thread loads the DLL file to call ShowMessageBox() export that calls MessageBox().
// Secondary thread frees DLL but the dialog box is still visible.
// When OK is clicked the freed memory is dereferenced.
#include <Windows.h>

static HMODULE handle;

DWORD WINAPI Thread(LPVOID lpParam)
{
   printf("[Thread] Waiting 5 seconds.\n");
   Sleep(5000);
   FreeLibrary(handle);
   printf("[Thread] FreeLibrary() called. Click OK to dereference freed memory.\n");
   return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
   typedef void (WINAPI *FUNC)(void);
   FUNC ShowMessageBox;

   handle = LoadLibrary(L"DialogDLL.dll");
   printf("LoadLibrary() called.\n");

   ShowMessageBox = (FUNC)GetProcAddress(handle, "ShowMessageBox");

   CreateThread(NULL, 0, Thread, NULL, NULL, NULL);
   printf("Thread created for FreeLibrary().\n");

   printf("MessageBox pops up.\n");
   ShowMessageBox();
   return 0;
}


// This is the DLL file.
// It has an export that calls MessageBox()
extern "C" __declspec( dllexport ) void ShowMessageBox();

void ShowMessageBox()
{
    MessageBox(NULL, L"...shown by the DLL that can be unloaded while this dialog box is still visible.\n\nThe unloaded DLL
can be dereferenced when OK is clicked.", L"This is a dialog box...", MB_OK);
}
The complete source code for Visual C++ 2010 can be downloaded from here. When executing the program it looks like below.

When OK is clicked the instruction dereferences freed memory.
Just a note that the control transfer instruction to dereference freed memory is not call that can be seen in v-table bugs but ret.

March 13, 2013

Flash Player Unloading Vulnerability

Opera unloads Flash Player after two minutes of not being used. Flash Player can create dialog that can run even when the player itself is unloaded. When it's unloaded, the running dialog makes a call back to the unloaded module, in a time window.

If an attacker can exploit the time window between the unload and the dereference, it's possible to redirect the execution flow.

While experimenting, I used heap spray to inject 0xCC bytes to the deleted memory. I succeeded once of many attempts and this suggests it's practically possible to create an exploit that could inject malicious code within the time window.

When investigated this vulnerability, I wanted evidence to the question: what module unloads the Flash Player? I used Windbg to place breakpoint at unload events. I let the application to trigger the unload events, and when the debugger hit the breakpoint, printed the call stack.
0:014> sxe ud
0:014> g
Unload module C:\Windows\SysWOW64\Macromed\Flash\NPSWF32_11_4_402_287.dll at 54760000
eax=00000000 ebx=035f5584 ecx=00000000 edx=00000000 esi=035f5bc8 edi=00000000
eip=77b1fc72 esp=0037dab0 ebp=0037db30 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
ntdll!ZwUnmapViewOfSection+0x12:
77b1fc72 83c404          add     esp,4
0:000> kc
ntdll!ZwUnmapViewOfSection
ntdll!LdrpUnloadDll
ntdll!LdrUnloadDll
KERNELBASE!FreeLibrary
WARNING: Stack unwind information not available. Following frames may be wrong.
Opera_534b0000!OpSetSpawnPath
Opera_534b0000!OpWaitFileWasPresent
I saw the Flash Player was freed by Opera indeed.

I needed the answer for the question also: what module created the thread that calls back to the unloaded module? Here are the series of Windbg commands used to get the answer.
sxn et
sxn ud
bp CreateRemoteThreadEx "kc; gu; !handle eax 8; gc"
g

KERNELBASE!CreateRemoteThreadEx
kernel32!CreateThreadStub
WARNING: Stack unwind information not available. Following frames may be wrong.
NPSWF32_11_4_402_287!native_ShockwaveFlash_TCallLabel
Opera_534b0000!OpGetNextUninstallFile
Opera_534b0000!OpGetNextUninstallFile
NPSWF32_11_4_402_287!NP_Shutdown
NPSWF32_11_4_402_287
NPSWF32_11_4_402_287!DllUnregisterServer
Opera_534b0000!OpWaitFileWasPresent
ntdll!TppPoolReserveTaskPost
ntdll!TppTimerpSet
Opera_534b0000!OpGetNextUninstallFile
Opera_534b0000!OpSetLaunchMan
Opera_534b0000!OpSetLaunchMan
Handle a20
  Object Specific Information
    Thread Id   88ac.1700
    Priority    10
    Base Priority 0
    Start Address 5497083d NPSWF32_11_4_402_287!native_ShockwaveFlash_TCallLabel
ModLoad: 6bda0000 6bdd0000   C:\Windows\SysWOW64\wdmaud.drv
ModLoad: 72cb0000 72cb4000   C:\Windows\SysWOW64\ksuser.dll
ModLoad: 6d9e0000 6d9e7000   C:\Windows\SysWOW64\AVRT.dll
ModLoad: 6cad0000 6cad8000   C:\Windows\SysWOW64\msacm32.drv
ModLoad: 6bd80000 6bd94000   C:\Windows\SysWOW64\MSACM32.dll
ModLoad: 6bd70000 6bd77000   C:\Windows\SysWOW64\midimap.dll
Exit thread 6:3f90, code 0
Exit thread 7:4074, code 0
Unload module C:\Windows\SysWOW64\Macromed\Flash\NPSWF32_11_4_402_287.dll at 54760000
Unload module C:\Windows\system32\WINSPOOL.DRV at 736f0000
(88ac.1700): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000102 ebx=00000000 ecx=75a914d0 edx=00000000 esi=11c8d000 edi=11c8d470
eip=549706c0 esp=0aacfd38 ebp=0aacfd80 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
<Unloaded_NPSWF32_11_4_402_287.dll>+0x2106c0:
549706c0 ??              ???
I saw that thread 88ac.1700 is created by the Flash Player. When the player is unloaded the thread is still running. Finally, the thread calls back to the unloaded module. Therefore, I knew Flash Player created the thread that calls back to its own module that has been unloaded.

And here is some interesting observation.

When started to look into triggering a dialog in Flash Player I created the following ActionScript that executes an infinite loop.
class InfiniteLoop {
static function main() {
           for (var i = 0; i < 1;) {}
}
}
I built the Flash file with the command below.
mtasc.exe -swf InfiniteLoop.swf -main -header 125:125:20 InfiniteLoop.as
The Flash file triggers a slow script warning dialog. I was able to unload and to crash the Flash Player while the dialog was still running. I achieved this with version 11.4.402.278. When reported the problem to Opera they couldn't reproduce it. That time there was a Flash Player update, and I found it out that they used the latest version of Flash Player that was 11.4.402.287. With the latest version, I couldn't reproduce the problem either.

It got me thinking if Adobe fixed security problem either silently or "accidentally". When I checked the release notes of the latest version I didn't see indication of this kind of fix. I still don't know what had happened between the two releases but thought to investigate this issue further. I tried to trigger the bug via different code paths. I looked at my Flash file collection to dig out a file that triggers a dialog. And here it is, with the one I found, I could crash the player with the same call stack as before.

Initially, I thought Opera could fix this issue by leaving the module permanent in the address space, so I reported this to Opera. However, they notified Adobe after confirming it's not the problem in Opera (though they considered it as a stability issue). Adobe received the report at the end of November, 2012. The bug is now fixed in the security update that has a number of APSB13-09 at 12 March, 2013.

The preliminary version of this blog post was reviewed by Adobe. The preliminary version is same to the published version apart from some changes in the wording.

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.

September 2, 2012

Timeline for Fix of an Arbitrary Address Write Bug

In today's post I'm writing about an arbitrary address write bug in Flash Player in Firefox (CVE-2012-4171) that is now fixed.

The issue was reported to Mozilla, but the fix made by Adobe as it turned out it was a bug in the Flash Player. The bug was tracked in Mozilla's bug tracking system (BugZilla) here [still restricted at the time of writing].

To trigger this vulnerability there is no requirement to use malformed data in any way. All the constructs can be legitimate. The PoC demonstrates when the security dialog box is shown it is possible to navigate to an other page that pops up another security dialog while the first dialog is still visible. When the second dialog is OK'd Flash Player crashes.

Below code snippet demonstrates the vulnerable code path.
mov     ecx,dword ptr [esi+4]           *(1)
<STRIPPED>
mov     esi,ecx
add     dword ptr [esi+1B8h],0FFFFFFFFh *(2)
At line (1) [ESI+4] is an address in a valid heap region. The heap can be arranged to contain user controlled data. Therefore, at line (2) an attacker can write arbitrary address using add instruction. Due to depending on add instruction the attacker has limited control what data to write.

Below is the timeline for the fix.
Days Date Channel Action
0 days 25-Jan-2010 E-mailReport sent to Mozilla.
0 days 25-Jan-2010 E-mailMozilla confirms the behavior described in the report. A case opened in the bug tracking database (BugZilla).
731 days 26-Jan-2012 BugZillaA Mozilla engineer says he can reproduce the issue with Firefox 9 on Windows 7 but cannot reproduce with nightly build.
731 days 26-Jan-2012 BugZilla An Adobe engineer says they will triage this issue ASAP.
749 days 13-Feb-2012 BugZilla A Mozilla engineer asks for status update from Adobe.
749 days 13-Feb-2012 BugZilla An Adobe engineer confirms he cannot reproduce the crash.
749 days 13-Feb-2012 BugZilla An Adobe engineer confirms he can reproduce the crash by experimenting with waiting times before clicking "OK" on the prompt.
749 days 13-Feb-2012 BugZilla Reporter recommends to switch off plugin-container introduced since the report to get consistent crash state.
779 days 14-March-2012 E-mailReporter asks for status update, and points out the existing testcase reliably crashes Firefox when plugin-container disabled.
779 days 14-March-2012 E-mailMozilla confirm there is no other update on the case, than seen in BugZilla. Mozilla asks to put additional information about crashes.
780 days 15-March-2012 BugZilla Reporter adds additional information about crashes.
780 days 15-March-2012 E-mailReporter asks for an estimation of the date of the fix.
780 days 15-March-2012 E-mailMozilla confirm they don't have an estimation. They say to have to see what the developers can do with it in the short term.
780 days 15-March-2012 E-mailIn response to an earlier email Mozilla say "flash bugs are often slow to be fixed".
805 days 9-Apr-2012 E-mailReporter decided to share crash information with CERT, and asked if they can help motivating the vendor to issue a patch.
805 days 9-Apr-2012 E-mailCERT confirm they have spoken with the vendor.
806 days 10-Apr-2012 BugZilla Mozilla say they effectively mitigated this issue with out of process plugins and they require a testcase which crashes Firefox in an exploitable manner.
806 days 10-Apr-2012 BugZilla Reporter responses that existing testcase crashes Firefox in 1/10 ratio on reporter side. With plugin-container disabled it crashes Firefox in 10/10 ratio.
807 days 11-Apr-2012 BugZilla An Adobe engineer confirms they cannot reproduce the issue.
808 days 12-Apr-2012 BugZilla Reporter recommends to disable plugin-container to get a consistent crash state. Reporter also highlights plugin container is just a mitigation that could be bypassed.
808 days 12-Apr-2012 BugZilla A Mozilla Security Researcher asks how the plugin-container could be bypassed.
808 days 12-Apr-2012 BugZilla Reporter highlights attack surfaces but he also states discussing how to bypass mitigation is out of the scope of this bug.
814 days 18-Apr-2012 BugZilla Adobe say they have a good set of test cases for this issue now, and this will be fixed in the following release.
861 days 4-June-2012 BugZilla Adobe confirm it is fixed in 11.4.400.128. [This seems to be an internal build]
939 days 21-Aug-2012 WebFix released in 11.4.402.265. To see Adobe's Security Bulletin click here.
N/A 27-Aug-2012 BugZilla Adobe confirm 11.4.402.265 is released on 21st of August and mark the bug as fixed.
N/A 29-Aug-2012 E-mailReporter checks Adobe's Security Bulletin and realizes this bug is not mentioned in it. Asks Adobe regarding CVE number.
N/A 30-Aug-2012 E-mailAdobe confirm the Security Bulletin has been updated with the CVE number.
This timeline contains the technically important communications. If you are aware of that I missed something that you think is important to mention, please let me know and I'll update this page.

Thanks for those who involved from Mozilla, Adobe and CERT.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.