[funsec] Another WMF flaw without a Microsoft patch

H D Moore funsecspam at digitaloffense.net
Mon Jan 9 14:27:36 CST 2006


More where that came from. The fun thing about these is that they DO apply 
to Windows 96, 98, 2000-2003, Vista. You can trigger it via RTF, directly 
inside IE, and anything else that loads metafiles. A fun bug you can find 
in a certain WMF parsing application...:

uint_size = wmf_header.size * 2;
ptr = malloc(uint_size);
read(fd, ptr, uint_size - sizeof(wmf_header));

:-)

-HD

On Monday 09 January 2006 12:25, Richard M. Smith wrote:
> -----Original Message-----
> From: frankruder at hotmail.com [mailto:frankruder at hotmail.com]
> Sent: Saturday, January 07, 2006 12:08 AM
> To: bugtraq at securityfocus.com
> Subject: Microsoft Windows GRE WMF Format Multiple Memory Overrun
> Vulnerabilities
>
> Microsoft Windows GRE WMF Format Multiple Memory Overrun
> Vulnerabilities
>
> by cocoruder
> page:http://ruder.cdut.net
> email:frankruder_at_hotmail.com
>
> Last Update:2006.01.07
> class:design error
> Remote:yes
> local:yes
>
> Product Affected:
> Microsoft Windows XP SP2
> Microsoft Windows XP SP1
> Microsoft Windows Server 2003 SP1
> Microsoft Windows Server 2003
> Microsoft Windows ME
> Microsoft Windows 98se
> Microsoft Windows 98
> Microsoft Windows 2000SP4
>
> Vendor:
> www.microsoft.com

> Overview:
> Microsoft Windows GRE(Graphics Rendering Engine) has been discovered
> multiple memory overrun vulnerabilities while rendering WMF format
> file.Users who view the malicious WMF format file will bring a denial
> of service attack(explorer.exe will be restart).
>
> Details:
> there is 2 memory overrun vulnerabilities at least.
>
> 1.ExtCreateRegion call result in memory overrun vulnerability HRGN
> ExtCreateRegion(
>   CONST XFORM *lpXform,     // transformation data
>   DWORD nCount,             // size of region data
>   CONST RGNDATA *lpRgnData  // region data buffer );
>
> WMFRECORD structure:
> typedef struct _StandardMetaRecord
> {
>     DWORD Size;          /* Total size of the record in WORDs */
>     WORD  Function;      /* Function number (defined in WINDOWS.H) */
>     WORD  Parameters[];  /* Parameter values passed to function */ }
> WMFRECORD;
>
> the Parameters is likely about:
> typedef	struct 	_Parameters
> {
> 	char	unknow1[0x0a];
> 	WORD	All_PointtStruct_Num;	//the total following "
> PointtStruct" number
> 	char	unknow2[0x0a];
> 	char	PointtStruct[];		//first  "PointtStruct"
> }Parameters;
>
> "PointtStruct"  structure:
> typedef	struct 	_PointtStruct
> {
> 	WORD	PointNum;		//
> 	WORD	Point[PointNum];	//
> 	char	unkonow[6];
> }PointtStruct;
>
> if we set 0xff to WMFRECORD.Function,PlayMetaFileRecord will compute
> the memory which will be allocate later,as following:
>
> .text:7F00FE07 loc_7F00FE07:                           ; CODE XREF:
> PlayMetaFileRecord+1256j
> .text:7F00FE07                 sub     eax, 3
> .text:7F00FE0A                 jnz     loc_7F022B9A    ; 0xff
> .text:7F00FE10                 movzx   ecx, word ptr [ebx+10h]	;get
> total "PointtStruct" number
> .text:7F00FE14                 mov     [ebp-88h], ecx		;save
> .text:7F00FE1A                 test    ecx, ecx
> .text:7F00FE1C                 jnz     short loc_7F00FE2E	;jmp
> .text:7F00FE1E                 xor     eax, eax
> .text:7F00FE20                 push    eax             ; int
> .text:7F00FE21                 push    eax             ; int
> .text:7F00FE22                 push    eax             ; int
> .text:7F00FE23                 push    eax             ; int
> .text:7F00FE24                 call    CreateRectRgn
> .text:7F00FE29                 jmp     loc_7F010494
> .text:7F00FE2E ;
> 哪哪哪哪哪哪哪哪&#21738
>;&#21
> 738;哪哪哪哪哪哪哪哪&#2
>1738;
> 哪哪哪哪哪哪哪哪&#21738
>;&#21
> 738;哪哪哪哪哪哪哪哪?
> .text:7F00FE2E
> .text:7F00FE2E loc_7F00FE2E:                           ; CODE XREF:
> PlayMetaFileRecord+C15j
> .text:7F00FE2E                 xor     edi, edi
> .text:7F00FE30                 mov     [ebp-8Ch], edi
> .text:7F00FE36                 lea     eax, [ebx+1Ch]		;get first
> "PointtStruct" address
> .text:7F00FE39                 mov     [ebp-90h], eax		;save
> .text:7F00FE3F                 and     [ebp-94h], edi
> .text:7F00FE45                 and     [ebp-98h], edi
> .text:7F00FE4B                 test    ecx, ecx
> .text:7F00FE4D                 jbe     short loc_7F00FE8C
> .text:7F00FE4F
> .text:7F00FE4F loc_7F00FE4F:                           ; CODE XREF:
> PlayMetaFileRecord+C83j
> .text:7F00FE4F                 movzx   ecx, word ptr [eax]	;get
> PointNum,here will trigger memory access error**
> .text:7F00FE52                 mov     edx, ecx
> .text:7F00FE54                 shr     edx, 1			;PointNum/2
> .text:7F00FE56                 add     edx, edi			;sum
> PointNum/2
> .text:7F00FE58                 cmp     edx, edi
> .text:7F00FE5A                 jb      loc_7F0106D5
> .text:7F00FE60                 mov     edi, edx
> .text:7F00FE62                 mov     [ebp-8Ch], edi
> .text:7F00FE68                 cmp     ecx, 7FFFFFFBh
> .text:7F00FE6E                 jnb     loc_7F0106D5
> .text:7F00FE74                 lea     eax, [eax+ecx*2+8]
> .text:7F00FE78                 inc     dword ptr [ebp-98h]	;counter+1
> .text:7F00FE7E                 mov     ecx, [ebp-98h]
> .text:7F00FE84                 cmp     ecx, [ebp-88h]		;cmp total
> "PointtStruct" number
> .text:7F00FE8A                 jb      short loc_7F00FE4F	;traverse
> all "PointtStruct"
> .text:7F00FE8C
> .text:7F00FE8C loc_7F00FE8C:                           		; CODE XREF:
> PlayMetaFileRecord+C46j
> .text:7F00FE8C                                         		;
> PlayMetaFileRecord+14D8j
> .text:7F00FE8C                 cmp     dword ptr [ebp-94h], 0
> .text:7F00FE93                 jnz     loc_7F022BA2
> .text:7F00FE99                 cmp     edi, 0FFFFFFDh
> .text:7F00FE9F                 jnb     loc_7F022BA2
> .text:7F00FEA5                 mov     eax, [ebp-8Ch]
> .text:7F00FEAB                 add     eax, 2
> .text:7F00FEAE                 shl     eax, 4
> .text:7F00FEB1                 mov     [ebp-9Ch], eax
> .text:7F00FEB7                 push    eax             ; uBytes
> .text:7F00FEB8                 push    0               ; uFlags
> .text:7F00FEBA                 call    ds:LocalAlloc		;will
> allocate memory normally.
> .text:7F00FEC0                 mov     edi, eax
>
> so when we set
> "Parameters.All_PointtStruct_Num","PointtStruct.PointNum" big
> enough,but not many enough "PointtStruct" structure,will trigger a
> memory access error on 7F00FE4F.
>
>
> 2.ExtEscape POSTSCRIPT_INJECTION result in memory overrun vulnerability
> int ExtEscape(
>   hdc,                  // handle to DC (HDC)
>   POSTSCRIPT_INJECTION, // nEscape param of ExtEscape
>   cbInput,              // size of input buffer
>   lpszInData,           // pointer to input (PSINJECTDATA *)
>   0,                    // cbOutput param of ExtEscape
>   NULL                  // lpszOutData param of ExtEscape
> );
>
> we can control cbInput and szInData,so when we set cbInput big
> enough(like 0xffff),but set szInData very small,will trigger a memory
> access error(7F027358) likely.
>
> .text:7F027312 loc_7F027312:                           ; CODE XREF:
> ExtEscape+11Ej
> .text:7F027312                                         ;
> ExtEscape+12Aj .text:7F027312                 test    byte ptr
> [ecx+4], 40h
> .text:7F027316                 jnz     loc_7F017CEC
> .text:7F02731C                 mov     ebx, [ebp+arg_8]		;we can
> cotrol this:cbSize
> .text:7F02731F                 add     ebx, 1Ah			;cbSize+0x1a
> .text:7F027322                 and     ebx, 0FFFFFFFCh
> ;cbSize+0x1a-4
> .text:7F027325                 mov     eax, large fs:18h
> .text:7F02732B                 mov     eax, [eax+30h]
> .text:7F02732E                 push    ebx
> .text:7F02732F                 push    0
> .text:7F027331                 push    dword ptr [eax+18h]
> .text:7F027334                 call    ds:RtlAllocateHeap	;allocate
> memory size=cbSize+0x16
> .text:7F02733A                 test    eax, eax
> .text:7F02733C                 jz      short loc_7F027385
> .text:7F02733E                 mov     ecx, [ebp+arg_4]
> .text:7F027341                 mov     [eax+0Ch], ecx
> .text:7F027344                 mov     ecx, [ebp+arg_8]
> .text:7F027347                 mov     [eax+10h], ecx
> .text:7F02734A                 mov     edx, ecx
> .text:7F02734C                 shr     ecx, 2
> .text:7F02734F                 sub     ebx, 8
> .text:7F027352                 mov     [eax+8], ebx
> .text:7F027355                 lea     edi, [eax+14h]
> .text:7F027358                 rep movsd			;copy,here
> will trigger a memory error likely**
> .text:7F02735A                 mov     ecx, edx
> .text:7F02735C                 and     ecx, 3
> .text:7F02735F                 rep movsb
> .text:7F027361                 mov     ecx, [ebp-4]
> .text:7F027364                 mov     edi, [ebp+arg_14]
> .text:7F027367                 lea     edx, [ecx+48h]
> .text:7F02736A                 mov     esi, [edx+4]
> .text:7F02736D                 mov     [eax+4], esi
>
> Exploit:
> first vul can test like this:
>  
> ...05020000FF0044444444444444444444FFFF33333333333333333333FFFF41424344
>... second vul can test like this:
>   ...0502000026001610FFFF4444444444444444...
> my blog can not be opened now:p,i will upload the exploit files to
> xfocus(www.xfocus.net) later,have fun:)
>
> Solution:
> Microsoft has not develop the patch,please unregister the Windows
> Picture and Fax Viewer (Shimgvw.dll)(see MS06-001).
>
> Thanks:
> thanks all my friends,Happy Weekday:)
>
> -EOF-
>
> _______________________________________________
> Fun and Misc security discussion for OT posts.
> https://linuxbox.org/cgi-bin/mailman/listinfo/funsec
> Note: funsec is a public and open mailing list.


More information about the funsec mailing list