ohio813 / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

Adobe Flash stack corruption when decoding JPEG-XR image #291

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Adobe Flash supports decoding of JPEG-XR images. This functionality is enabled 
by default. Diving into the function _jxr_r_MB_LP there is a stack overflow 
when indexing into an integer array. The flash code for this appears to closely 
match the ITU reference implementation 
(http://www.itu.int/rec/T-REC-T.835-201201-I/en) so I will reference that C 
code here to show the vulnerability:

file r_parse.c in function _jxr_r_MB_LP:
    0        int RLCoeffs[32] = {0};
    1        ...
    2        int num_nonzero = 0;
    3        ...
    4        num_nonzero = r_DECODE_BLOCK(image, str,
    5            chroma_flag, RLCoeffs, 1/*LP*/, location);
    6        
    7        DEBUG(" : num_nonzero = %d\n", num_nonzero);
    8        assert(num_nonzero <= 16);
    9
    10       if ((image->use_clr_fmt==1 || image->use_clr_fmt==2) && chroma_flag) {
    11           static const int remap_arr[] = {4, 1, 2, 3, 5, 6, 7};
    12           int temp[14];
    13           int idx;
    14           for (idx = 0 ; idx < 14 ; idx += 1)
    15               temp[idx] = 0;
    16 
    17           int remap_off = 0;
    18           if (image->use_clr_fmt==1/*YUV420*/)
    19               remap_off = 1;
    20
    21           int count_chr = 14;
    22           if (image->use_clr_fmt==1/*YUV420*/)
    23               count_chr = 6;
    24
    25           int k, i = 0;
    26           for (k = 0; k < num_nonzero; k+=1) {
    27               i += RLCoeffs[k*2+0];
    28               temp[i] = RLCoeffs[k*2+1];
    29               i += 1;
    30           }
    31       ...

On line 12 an integer array named temp is declared on the stack with 14 
elements. On line 26 that integer array is populated in a for loop running from 
0 to a maximum value of 16 iterations. The flash binary shows there is an 
explicit check on line 8 to bound num_nonzero to <= 16. On it's face this loop 
could write 2 integers beyond the end of the temp stack buffer. The last 
available index into tmp is 13 and the loop can write to index 14 and 15 just 
following the i+=1 on line 29.

However, it's worse than that due to the fact that the i variable increases not 
just by 1 each time through the loop but also by another user supplied value on 
line 27! The RLCoeffs array is populated with user data on line 4 with the 
r_DECODE_BLOCK function.

The stack frame for this function looks like this:

...
-000000BC RLCoeffs        dd 32 dup(?)
-0000003C temp            dd 14 dup(?)
-00000004 cookie          dd ?
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
+00000008 image           dd ?  
...

Compiler settings are good with the arrays at the end of the stack and a canary 
value between them and the saved ebp and return address. However, because we 
are writing to the stack non-sequentially it's possible to hop over the stack 
cookie and corrupt other bits of the stack.

PoC attached.

There are three files:
  LoadImg.as  - Action Script that will load the file img.img
  LoadImg.swf - Compiled LoadImg.as file
  img.img     - proof of concept JPEG-XR to exercise the vulnerability

When loading LoadImg.swf through Chrome flash will request and load the img.img 
file. The vulnerabile function is hit when the image is being decoded. It is 
called multiple times but the one that exercises the stack corruption will set 
num_nonzero to 8 and will then index out of bounds of the temp array to hop 
over the stack canary to corrupt saved ebp with a negitive value. A crash will 
occur two instructions after _jxr_r_MB_LP returns in Windows 7 32-bit running 
Chrome 41.0.2272.89:

63bd26dc e80e47ffff      call    pepflashplayer!PPP_ShutdownBroker+0x4d5bfc 
(63bc6def) ; _jxr_r_MB_LP
63bd26e1 83c410          add     esp,10h
63bd26e4 ff75f4          push    dword ptr [ebp-0Ch]  ss:0023:ffffffef=????????

eax=0716a340 ebx=0716a000 ecx=50b3cf2a edx=00000000 esi=0716a80c edi=001ad16c
eip=63bd26e4 esp=001ad0e4 ebp=fffffffb iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
pepflashplayer!PPP_ShutdownBroker+0x4e14f1:
63bd26e4 ff75f4          push    dword ptr [ebp-0Ch]  ss:0023:ffffffef=????????

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.

Original issue reported on code.google.com by scvi...@google.com on 16 Mar 2015 at 6:51

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by scvi...@google.com on 17 Mar 2015 at 12:21

GoogleCodeExporter commented 9 years ago

Original comment by scvi...@google.com on 2 Apr 2015 at 5:45

GoogleCodeExporter commented 9 years ago

Original comment by cev...@google.com on 10 Apr 2015 at 9:34

GoogleCodeExporter commented 9 years ago
Fixed: https://helpx.adobe.com/security/products/flash-player/apsb15-06.html

Original comment by cev...@google.com on 14 Apr 2015 at 6:22

GoogleCodeExporter commented 9 years ago

Original comment by scvi...@google.com on 22 Apr 2015 at 3:29