New issue
Advanced search Search tips
Starred by 2 users
Status: Fixed
Owner:
Closed: Jun 2015
Cc:



Sign in to add a comment
VMware Workstation: vprintproxy.exe multiple vulnerabilities in EMF record enumeration callback
Project Member Reported by kost...@google.com, Mar 12 2015 Back to list
Version: VMware Workstation 11.1
Host Platform: Windows 8.1 amd64

Summary:
Printer virtualization under VMware Workstation involves a vprintproxy.exe process launched by vmware-vmx.exe on the Host. It will receive and process EMFSPOOL files sent by a Guest on its COM1 port, if a virtual printer has been added to the VM hardware (default). Several vulnerabilities in this component allow an unprivileged Guest user to execute code on the Host.

Description:
The CEMF::EnhMetaFileProc function in TPView.dll is used as a callback to EnumEnhMetaFile, and applies some specific processing to several EMR types prior to “playing” them. The sanity of those records poorly checked, leading to multiple out-of-bounds read or write operations.

.text:10020CFA                   case_EMR_SMALLTEXTOUT:                  ; size_t
.text:10020CFA FF 77 04                          push    dword ptr [edi+4]
.text:10020CFD E8 D1 91 05 00                    call    _malloc
.text:10020D02 8B F0                             mov     esi, eax
.text:10020D04 59                                pop     ecx
.text:10020D05 3B F3                             cmp     esi, ebx
.text:10020D07 0F 84 BC 00 00 00                 jz      loc_10020DC9
.text:10020D0D FF 77 04                          push    dword ptr [edi+4] ; size_t
.text:10020D10 57                                push    edi             ; void *
.text:10020D11 56                                push    esi             ; void *
.text:10020D12 E8 E9 82 05 00                    call    _memcpy
.text:10020D17 83 C4 0C                          add     esp, 0Ch
.text:10020D1A 39 5D DC                          cmp     [ebp+var_24], ebx
.text:10020D1D B9 00 01 00 00                    mov     ecx, 100h
.text:10020D22 74 2F                             jz      short loc_10020D53
.text:10020D24 8B 46 0C                          mov     eax, [esi+0Ch]  ; (1)
.text:10020D27 D9 46 20                          fld     dword ptr [esi+20h] ; (2)
.text:10020D2A D8 0D 98 25 0C 10                 fmul    ds:g_fMinus1
.text:10020D30 F7 D8                             neg     eax
.text:10020D32 89 46 0C                          mov     [esi+0Ch], eax  ; (3)
.text:10020D35 8B 46 14                          mov     eax, [esi+14h]  ; (4)
.text:10020D38 85 C1                             test    ecx, eax
.text:10020D3A D9 5E 20                          fstp    dword ptr [esi+20h] ; (5)

Here, the size of the EMR_SMALLTEXTOUT record at [edi+4] is not checked to be at least 0x34 prior to operations being carried on fields of the structure.

.text:10020DDE                   loc_10020DDE:                           ; CODE XREF: CEMF::EnhMetaFileProc+5E7j
.text:10020DDE FF 77 04                          push    dword ptr [edi+4] ; size_t
.text:10020DE1 57                                push    edi             ; void *
.text:10020DE2 56                                push    esi             ; void *
.text:10020DE3 E8 18 82 05 00                    call    _memcpy
.text:10020DE8 83 C4 0C                          add     esp, 0Ch
.text:10020DEB 39 5D DC                          cmp     [ebp+var_24], ebx
.text:10020DEE 74 BB                             jz      short loc_10020DAB
.text:10020DF0 8B 46 28                          mov     eax, [esi+28h]  ; (1)
.text:10020DF3 D9 46 20                          fld     dword ptr [esi+20h] ; (2)
.text:10020DF6 D8 0D 98 25 0C 10                 fmul    ds:g_fMinus1
.text:10020DFC F7 D8                             neg     eax
.text:10020DFE 89 46 28                          mov     [esi+28h], eax  ; (3)
.text:10020E01 8B 46 14                          mov     eax, [esi+14h]  ; (4)
.text:10020E04 F7 D8                             neg     eax
.text:10020E06 D9 5E 20                          fstp    dword ptr [esi+20h] ; (5)
.text:10020E09 89 46 14                          mov     [esi+14h], eax  ; (6)
.text:10020E0C 8B 46 0C                          mov     eax, [esi+0Ch]  ; (7)
.text:10020E0F F7 D8                             neg     eax
.text:10020E11 F6 46 34 04                       test    byte ptr [esi+34h], 4 ; (8)
.text:10020E15 89 46 0C                          mov     [esi+0Ch], eax  ; (9)
.text:10020E18 74 91                             jz      short loc_10020DAB
.text:10020E1A 8B 46 44                          mov     eax, [esi+44h]  ; (10)
.text:10020E1D F7 D8                             neg     eax
.text:10020E1F 89 46 44                          mov     [esi+44h], eax  ; (11)
.text:10020E22 8B 46 3C                          mov     eax, [esi+3Ch]  ; (12)
.text:10020E25 F7 D8                             neg     eax
.text:10020E27 89 46 3C                          mov     [esi+3Ch], eax  ; (13)

Same issue here for an EMR_EXTTEXTOUTW record, there is no minimum size enforced for [edi+4], resulting in multiple OOB read and write operations.

.text:10020E2F                   case_EMR_EXTCREATEFONTINDIRECTW:        ; CODE XREF: CEMF::EnhMetaFileProc+50j
.text:10020E2F FF 77 04                          push    dword ptr [edi+4] ; size_t
.text:10020E32 E8 9C 90 05 00                    call    _malloc
.text:10020E37 8B F0                             mov     esi, eax
.text:10020E39 59                                pop     ecx
.text:10020E3A 3B F3                             cmp     esi, ebx
.text:10020E3C 89 75 10                          mov     [ebp+lpEMFR], esi
.text:10020E3F 74 88                             jz      short loc_10020DC9
.text:10020E41 FF 77 04                          push    dword ptr [edi+4] ; size_t
.text:10020E44 57                                push    edi             ; void *
.text:10020E45 56                                push    esi             ; void *
.text:10020E46 E8 B5 81 05 00                    call    _memcpy
.text:10020E4B 83 C6 28                          add     esi, 28h        ; LogFontExDv.LogFont.FaceName
.text:10020E4E 83 C4 0C                          add     esp, 0Ch
.text:10020E51 66 39 1E                          cmp     [esi], bx       ; (1)
.text:10020E54 74 1D                             jz      short loc_10020E73
.text:10020E56 8B 45 18                          mov     eax, [ebp+arg_10]
.text:10020E59 53                                push    ebx             ; int
.text:10020E5A 56                                push    esi             ; wchar_t * (2)
.text:10020E5B 8D 48 34                          lea     ecx, [eax+34h]
.text:10020E5E 89 4D C8                          mov     [ebp+var_38], ecx
.text:10020E61 E8 F1 11 08 00                    call    sub_100A2057

And with EMR_EXTCREATEFONTINDIRECTW.

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.

 
Project Member Comment 1 by kost...@google.com, Mar 12 2015
Sample dump of the OOB read for a small EMR_EXTCREATEFONTINDIRECTW:

0:011:x86> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************


FAULTING_IP: 
TPView+20e51
0ba50e51 66391e          cmp     word ptr [esi],bx

EXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 000000000ba50e51 (TPView+0x0000000000020e51)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: 000000000bc10008
Attempt to read from address 000000000bc10008

CONTEXT:  0000000000000000 -- (.cxr 0x0;r)
eax=0bc0ffe0 ebx=00000000 ecx=00000006 edx=00000000 esi=0bc10008 edi=08ce0084
eip=0ba50e51 esp=098df0ec ebp=098df204 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
TPView+0x20e51:
0ba50e51 66391e          cmp     word ptr [esi],bx        ds:002b:0bc10008=????

FAULTING_THREAD:  0000000000001524

PROCESS_NAME:  vprintproxy.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_PARAMETER1:  0000000000000000

EXCEPTION_PARAMETER2:  000000000bc10008

READ_ADDRESS:  000000000bc10008 

FOLLOWUP_IP: 
TPView+20e51
0ba50e51 66391e          cmp     word ptr [esi],bx

NTGLOBALFLAG:  2000000

APPLICATION_VERIFIER_FLAGS:  0

APP:  vprintproxy.exe

ANALYSIS_VERSION: 6.3.9600.17298 (debuggers(dbg).141024-1500) amd64fre

BUGCHECK_STR:  APPLICATION_FAULT_INVALID_POINTER_READ_ZEROED_STACK

PRIMARY_PROBLEM_CLASS:  INVALID_POINTER_READ

DEFAULT_BUCKET_ID:  INVALID_POINTER_READ

LAST_CONTROL_TRANSFER:  from 0000000076c7d190 to 000000000ba50e51

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
098df204 76c7d190 83010730 0b96eff8 0bc0ffe0 TPView+0x20e51
098df2bc 76c7d3dc 0ba507e0 098df438 098df498 GDI32!bInternalPlayEMF+0x79b
098df2d0 0ba50749 83010730 52461761 0ba507e0 GDI32!EnumEnhMetaFile+0x2c
098df4d8 0ba48343 0f848c00 098df518 00000000 TPView+0x20749
098df568 0ba47df6 098df584 000003b3 0badbc30 TPView+0x18343
098df5e4 0bad6200 0f998ea0 0f998ea0 0b124e88 TPView+0x17df6
098df658 0bad5ed1 0000000f 00000000 0baf6128 TPView!JP2_General_CheckICC+0x61a70
098df678 0bad4ede 0000000f 00000000 00000000 TPView!JP2_General_CheckICC+0x61741
098df6d8 0bad50f9 0f998ea0 00000000 0000000f TPView!JP2_General_CheckICC+0x6074e
098df6f8 76938e71 008304cc 0000000f 00000000 TPView!JP2_General_CheckICC+0x60969
098df724 7693aefd 0bad50c5 008304cc 0000000f USER32!_InternalCallWinProc+0x2b
098df7b8 7693932c 0bad50c5 00000000 0000000f USER32!UserCallWinProcCheckWow+0x262
098df818 76939529 066e10c0 00000000 0000000f USER32!DispatchClientMessage+0xdc
098df858 77670996 098df870 00000000 098df8d0 USER32!__fnDWORD+0x49
098df88c 76940f1e 0f96aeb0 fecf0706 0f96aeb0 ntdll_77630000!KiUserCallbackDispatcher+0x36
098df8e0 7693a6e0 f742ffe6 0f96aeb0 0bad3e0f USER32!DispatchMessageWorker+0x313
098df8ec 0bad3e0f 0f96aeb0 00000001 0f96ae80 USER32!DispatchMessageW+0x10
098df8fc 0bad3930 0919fa0c 0f96ae80 098df97c TPView!JP2_General_CheckICC+0x5f67f
098df914 0bad3598 0baab40f 0f968f80 0f968f80 TPView!JP2_General_CheckICC+0x5f1a0
00000000 00000000 00000000 00000000 00000000 TPView!JP2_General_CheckICC+0x5ee08


STACK_COMMAND:  .cxr 0x0 ; kb

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  tpview+20e51

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: TPView

IMAGE_NAME:  TPView.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  51dfe66e

FAILURE_BUCKET_ID:  INVALID_POINTER_READ_c0000005_TPView.dll!Unknown

BUCKET_ID:  APPLICATION_FAULT_INVALID_POINTER_READ_ZEROED_STACK_tpview+20e51

ANALYSIS_SOURCE:  UM

FAILURE_ID_HASH_STRING:  um:invalid_pointer_read_c0000005_tpview.dll!unknown

FAILURE_ID_HASH:  {b43e8298-07ae-a18e-7c4a-447718582ccb}

Followup: MachineOwner
---------


Project Member Comment 2 by scvitti@google.com, Mar 19 2015
Labels: -Reported-Mar-5-2015 Reported-2015-Mar-5
Project Member Comment 3 by kost...@google.com, Jun 2 2015
Labels: Deadline-Grace
Project Member Comment 4 by kost...@google.com, Jun 2 2015
Labels: Deadline-Exceeded
Project Member Comment 5 by kost...@google.com, Jun 9 2015
Labels: -Restrict-View-Commit
Project Member Comment 6 by kost...@google.com, Jun 9 2015
Status: Fixed
Project Member Comment 7 by kost...@google.com, Jun 9 2015
VMware advisory VMSA-2015-0004:
https://www.vmware.com/security/advisories/VMSA-2015-0004.html
Sign in to add a comment