The blog continues at suszter.com/ReversingOnWindows

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.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.