Exploit-DB #18067
Description: Microsoft Excel 2007 SP2 - Buffer Overwrite (MS11-021)
Type: local
Platform: windows
Date: 2011-11-02
Author: Abysssec

Exploit:
Abysssec Research

1) Advisory information

  Title             :  Microsoft Excel 2007 SP2 Buffer Overwrite
Vulnerability
  Analysis          :  Abysssec.com
  Vendor            :  http://www.microsoft.com
  Impact            :  Critical
  Contact           :  info [at] abysssec.com
  Twitter           :  @abysssec

Microsoft :
A remote code execution vulnerability exists in the way that Microsoft
Excel handles specially crafted Excel files.
An attacker who successfully exploited this vulnerability could take
complete control of an affected system.
An attacker could then install programs; view, change, or delete data;
or create new accounts with full user rights.


each excel file can contain multiple  BOF (2057) records . This record
specifies the first substream associated with workbook.
One of the fields in these records, specify substream recordd to come
with. This field can be extracted from sub_3018F0C2 function.

.text:301A0C87                 push    [ebp+arg_2C]
.text:301A0C8A                 mov     ecx, [ebp+var_14]
.text:301A0C8D                 push    1
.text:301A0C8F                 call    sub_3018F0C2
.text:301A0C94                 mov     ecx, eax
.text:301A0C96                 mov     eax, [ebp+arg_24]
.text:301A0C99                 cmp     eax, ebx
.text:301A0C9B                 mov     [ebp+var_10], ecx
.text:301A0C9E                 jz      short loc_301A0CA2
.text:301A0CA0                 mov     [eax], ecx


If the field value is equal with 400, sub_3019DFBA function is called to
check file type. if file type is xls EXCEL.exe will display a message If
approved it will continue to run the code.if you change file extension
to xlb there will be any message. After this step sub_3053F626 function
will be executed. This function will parse the next BOF records.

.text:304D4E9D                 cmp     [ebp+arg_20], ebx
.text:304D4EA0                 jnz     short loc_304D4EC6
.text:304D4EA2                 test    dword ptr word_30EDCF9C, 2000000h
.text:304D4EAC                 jnz     short loc_304D4EC6
.text:304D4EAE                 mov     edx, [ebp+arg_C]
.text:304D4EB1                 mov     ecx, [ebp+arg_8]
.text:304D4EB4                 push    3Fh
.text:304D4EB6                 call    sub_3019DFBA
.text:304D4EBB                 cmp     eax, ebx
.text:304D4EBD                 mov     [ebp+var_8], eax
.text:304D4EC0                 jz      loc_304D4FD3
.text:304D4EC6
.text:304D4EC6 loc_304D4EC6:                           ; CODE XREF:
sub_301A0BC7+3342D9j
.text:304D4EC6                                         ;
sub_301A0BC7+3342E5j
.text:304D4EC6                 push    ebx
.text:304D4EC7                 push    dword_30EB89A4
.text:304D4ECD                 push    [ebp+var_C]
.text:304D4ED0                 call    sub_3053F626
.text:304D4ED5                 cmp     dword_30F5E64C, ebx
.text:304D4EDB                 mov     [ebp+var_8], eax
.text:304D4EDE                 jz      short loc_304D4EE7
.text:304D4EE0                 cmp     eax, ebx
.text:304D4EE2                 jz      short loc_304D4EE7

one of records may come after BOF,is undocumented record which have
record type equal to 0xA7 (167).
for truly parsing this record should come with another record with 0x3C
(60) record type. if it meet this requirement
the length of records will be read and copied to the stack.

the function which operation of copying data records in the stack is
sub_30199E55. This function takes three arguments.
The first argument specifies the number of bytes to copy, which will
read from file. The second argument specifies the
destination of the copy and the third argument specifies the maximum
amount of data can be copied. values of the second
and third arguments based on the amount of computing reading from file
and into this cumpoting,computational error which may occur here ...


.text:3053F830                 call    sub_301A0A01
.text:3053F835                 cmp     eax, 3Ch
.text:3053F838                 mov     [ebp+var_ED4], eax
.text:3053F83E                 jnz     loc_30540488
.text:3053F844                 call    sub_301A0A01
.text:3053F849                 mov     ecx, [ebp+var_EDC]
.text:3053F84F                 imul    ecx, [ebp+var_F00]
.text:3053F856                 mov     edi, eax
.text:3053F858                 mov     eax, [ebp+var_EE0]
.text:3053F85E                 lea     ebx, [ecx+eax+3]
.text:3053F862                 call    sub_301A0ABE
.text:3053F867                 push    0FFFFFFFDh
.text:3053F869                 pop     edx
.text:3053F86A                 sub     edx, ecx
.text:3053F86C                 add     eax, edx
.text:3053F86E                 push    eax             ; Dst
.text:3053F86F                 push    ebx             ; int
.text:3053F870                 mov     eax, edi
.text:3053F872                 call    sub_30199E55



 the vulnerability that exists here is that we can change the value of
parameter 3 whith our own values.
 program will not correcly controll third argument of sub_30199E55 this
and can result in the desired
 amount and location of desired data can overwrite in the stack.

.text:30199E60                 cmp     edi, [esp+4+Dst]
.text:30199E64                 ja      loc_303EE1B7
.text:30199E6A                 mov     ecx, [esp+4+arg_0]
.text:30199E6E                 push    ebx
.text:30199E6F                 mov     ebx, dword_30F726C0
.text:30199E75                 push    ebp
.text:30199E76                 mov     ebp, nNumberOfBytesToRead
.text:30199E7C                 push    esi
.text:30199E7D                 mov     [esp+10h+Dst], ecx
....
.text:30199E93                 mov     eax, [esp+10h+Dst]
.text:30199E97                 push    esi             ; Size
.text:30199E98                 lea     edx, dword_30F6E6B8[ebx]
.text:30199E9E                 push    edx             ; Src
.t