Vulnerability Analysis and POC construction of MS15-035 EMF file processing
MS15-035 is a vulnerability in Microsoft Graphics components that process enhanced primitive files (EMF) and may allow remote code execution.
Through patch comparison, we can see that some locations that may have an integer overflow are fixed, but these locations cannot be executed after many attempts.
However
Int _ thiscall MRSETDIBITSTODEVICE: bPlay (EMRSETDIBITSTODEVICE * this, HDC hdc, struct tagHANDLETABLE * a3, unsigned int a4)
The patch is an example. The pre-patch code is as follows:
After patching, the Code is as follows:
Obviously, the patch code imposes a limit on the minimum memory space allocated by LocalAlloc, but there is no limit before the patch is applied. Therefore, it is suggested that there may be a buffer write out of bounds.
By analyzing the function call chain, you can find that MRSETDIBITSTODEVICE: bPlay is called by PlayEnhMetaFileRecord.
PlayEnhMetaFileRecord calls different parsing functions based on the metadata block type in the EMF file. The EMF vulnerability CVE-2009-1217 described in the New EMF gdiplus. dll crash not exploitable for code execution Article 09 further confirms that the explorer process is to parse the EMF file's Metafile block through PlayEnhMetaFileRecord.
The following describes the structure of an EMF file. an EMF file consists of a variable-size Metafile block. Each metadata block is a variable-length ENHMETARECORD structure. The structure is as follows.
typedef struct tagENHMETARECORD { DWORD iType; DWORD nSize; DWORD dParm[1];} ENHMETARECORD, *PENHMETARECORD;
The SDK defines different iType types, as shown below.
DParm is a different structure based on the iType type, and EMR_SETDIBITSTODEVICE corresponds to EMRSETDIBITSTODEVICE.
typedef struct tagEMR{ DWORD iType; // Enhanced metafile record type DWORD nSize; // Length of the record in bytes. // This must be a multiple of 4.} EMR, *PEMR; typedef struct tagEMRSETDIBITSTODEVICE{ EMR emr; RECTL rclBounds; // Inclusive-inclusive bounds in device units LONG xDest; LONG yDest; LONG xSrc; LONG ySrc; LONG cxSrc; LONG cySrc; DWORD offBmiSrc; // Offset to the source BITMAPINFO structure DWORD cbBmiSrc; // Size of the source BITMAPINFO structure DWORD offBitsSrc; // Offset to the source bitmap bits DWORD cbBitsSrc; // Size of the source bitmap bits DWORD iUsageSrc; // Source bitmap info color table usage DWORD iStartScan; DWORD cScans;} EMRSETDIBITSTODEVICE, *PEMRSETDIBITSTODEVICE;
For the MRSETDIBITSTODEVICE: bPlay function, the first parameter is EMRSETDIBITSTODEVICE. To verify the correctness of the conjecture, a small emf file is generated through the program, and the iType is modified so that it can be executed to the MRSETDIBITSTODEVICE: bPlay function, and 0x54 (EMR_EXTTEXTOUTW) change to 0x50 (EMR_SETDIBITSTODEVICE ).
HDC hEmf = CreateEnhMetaFile( 0 , "1.emf" , NULL , NULL );RECT rect;rect.top = 0 ;rect.left = 0 ;rect.bottom = 20;rect.right = 200; char szStr[] = "WSAWSAW";ExtTextOut( hEmf , 0 , 0 , ETO_OPAQUE , &rect , szStr , sizeof(szStr) , NULL );CloseEnhMetaFile(hEmf); DeleteObject(hEmf);
In win7, the directory of the e-mapreduce file is not accessible. Because mspaint.exe is used to load the 1. emf file
Int _ thiscall MRSETDIBITSTODEVICE: bPlay (EMRSETDIBITSTODEVICE * this, HDC hdc, struct tagHANDLETABLE * a3, unsigned int a4)
Function, you can see that the data that ecx points to is consistent with the data in the file.
In order to implement the previous conjecture and cross-border write operations, it is assumed that cross-border write is implemented at (_ DWORD *) v8 + 5) = v4-> cbBitsSrc, this requires v4-> cbBmiSrc to be smaller than (64 ).
MRSETDIBITSTODEVICE: bCheckRecord checks the validity of the EMRSETDIBITSTODEVICE structure. The function is as follows.
Modify the emf file according to the check content so that it meets the MRSETDIBITSTODEVICE: bCheckRecord check conditions, and make v4-> cbBmiSrc smaller than (6*4 ), finally, the following file is obtained.
Use mspaint.exe to load the emf file. With windbg, we can see that all checks are bypassed, and the memory size allocated by LocalAlloc is 2.
After (_ DWORD *) v8 + 2) = v9 and (_ DWORD *) v8 + 5) = v4-> cbBitsSrc, cross-border buffer write operations will be implemented.
If you can use a script to display the emf file in a browser, the vulnerability may be exploited to execute code remotely. It is also worth mentioning that other functions such as MF16 _ * patched in the patch all have the following code segments. This is to verify the HDC type. These functions are executed only when the type is 0x660000, and I only get the HDC with the type of 0x660000 after calling CreateMetaFile, the HDC type is 0x10000. When the HDC type is 0x660000, PlayEnhMetaFile is called and PlayEnhMetaFileRecord is not executed.