OLE Automation Underflow Vulnerability – CVE-2011-0658
Diffing Binary Information
oleaut32.dll: 6.1.7600.16385 VS 6.1.7600.16722 (on Windows 7)
By running Darungrim, we have different function list below.
After playing around with these functions, I’ve found the interesting new blocks in “_PictLoadMetaFileRaw()”.
(If you google this function name, then you’ll find the vulnerability report for MS11-038, which says there’s integer overflow issues in this function. I should have googled first to save my time !!)
Yeah, this is what we exactly wanted to find. New conditional branches are added, and it seems interesting because 1) it’s compared with the constant value which is one of the common patch routines, and 2) arg8 is subtracted before being compared (hopefully integer overflow or underflow ??).
Probably this is a integer overflow patch. Let’s look at more details by tracing arg8 variable.
.text:6FC956DC mov ecx, [ebp+arg_8] .text:6FC956DF cmp ecx, 12h .text:6FC956E2 jl loc_6FC95856 .text:6FC956E8 lea eax, [ecx+14h] .text:6FC956EB cmp eax, ecx .text:6FC956ED jle loc_6FC95856 .text:6FC956F3 push eax ; dwBytes .text:6FC956F4 push 42h ; uFlags .text:6FC956F6 call ds:__imp__GlobalAlloc@8 ; GlobalAlloc(x,x) .text:6FC956FC mov [ebp+hMem], eax
Hummm… Before getting to that new branch, there’s memory allocation routine and the size argument of this is computed using arg8.
if ( arg8 < 0x12) goto ERROR (loc_6FC95856) if( arg8 +0x14 <= arg8) goto ERROR (loc_6FC95856) GlobalAlloc( 0x42, arg8+0x14)
Seems like there’s already integer overflow detection routine, so what can we do more with this ? (note that this routine is the same in the before & after binary)
.text:6FC95783 sub [ebp+arg_8], 14h .text:6FC95787 add ebx, 14h .text:6FC9578A jmp short loc_6FC957EE .text:6FC957EE loc_6FC957EE: ; CODE XREF: _PictLoadMetaFileRaw(CPicture *,IStream *,long,RECTS *)+7Aj .text:6FC957EE mov edi, [ebp+var_8] .text:6FC957F1 lea esi, [ebp+var_24] .text:6FC957F4 movsd .text:6FC957F5 movsd .text:6FC957F6 movsd .text:6FC957F7 movsd .text:6FC957F8 movsw .text:6FC957FA mov esi, [ebp+arg_8] .text:6FC957FD lea eax, [esi-12h] .text:6FC95800 push eax ; unsigned __int32 .text:6FC95801 push ebx ; void * .text:6FC95802 push [ebp+arg_4] ; struct IStream * .text:6FC95805 call ?HrRead@@YGJPAUIStream@@PAXK@Z ; HrRead(IStream *,void *,ulong)
This seems like HrRead( xxxx, xxxx, arg8-0x14-0x12). OHH?? Wait a moment. New branch block tried to assert “(arg8-0x14) > 0x12”.
Then, if 0x12 <= arg8 <= 0x26 (we really need to have a constraint solver!), we can trigger integer underflow on “lea eax, [esi-12h]”, which could unexpectedly lead to a huge value.
Good luck guys. It should be fun ! But I would rather work on next patch Tuesday 🙂
Messages to fuzzer developers
Simply putting critical values like 0xff, 0x80 and 0x00 would be no good anymore because everybody has done this already. As you can see in this vulnerability, we should put some arbitrary values in the length field to raise the exception, which requires to explore whole 1/2/4 bytes space. It’s time to consider using ‘constraint solvers’ to find better critical values.