MSWord

All posts tagged MSWord

Recently I’ve been researching into ActiveX controls in Office documents as I had some ideas I wanted to test out after reading Dominic Wang’s paper “Understanding Microsoft Word OLE Exploit Primitives: Exploiting CVE-2015-1642 Microsoft Office CTaskSymbol Use-After-Free Vulnerability” [1] and Haifei Li’s and Bing Sun’s presentation slides “Attacking Interoperability: An OLE Edition” [2].

Some vulnerabilities that have been exploited in the past (CVE-2013-3906, CVE-2015-2424, CVE-2015-1641) have been embedding ActiveX controls to perform the heap spray whether be in Open XML format or encapsulated in RTF format. During my tests it was obvious that spraying the heap just took ages, waiting sometimes minutes before triggering the vulnerability. The exploits I examined either used one large ActiveX1.bin file or multiple ActiveX[x].bin files. This post just shows how we can spray the heap in seconds rather than minutes, mainly working with MS Word documents on a fully patched Windows 7 32bit with Office Professional 2010 with Open XML formatted files.

Office Open XML structure
I started looking into an Open XML formatted document which is basically a zip archive so just by renaming the extension to a zip we can extract, make changes to the files and zip it up again.  Running the tree command in the extracted folder of a simple Word document we see the files listed below which contains one ActiveX object.

|   [Content_Types].xml
|
+---docProps
|       app.xml
|       core.xml
|
+---word
|   |   document.xml
|   |   fontTable.xml
|   |   settings.xml
|   |   styles.xml
|   |   stylesWithEffects.xml
|   |   webSettings.xml
|   |
|   +---activeX
|   |   |   activeX1.bin
|   |   |   activeX1.xml
|   |   |
|   |   \---_rels
|   |           activeX1.xml.rels
|   |
|   +---media
|   |       image1.wmf
|   |
|   +---theme
|   |       theme1.xml
|   |
|   \---_rels
|           document.xml.rels
|
\---_rels
        .rels

activeX1.bin is our Compound Document Format file which would contain our sprayed data and activeX1.xml would contain our classid to be used. When adding or removing ActiveX objects manually there are 5 files you’ll need to update

[Content_Types].xml   – contains entries pointing to individual activeX[x].xml entries
document.xml                – contains ids which refer activex[x].xml files set in document.xml.rels
document.xml.rels        – contains individual image[x].wmf and activeX[x].xml entries, unique rIds
activeX[x].xml               – Calls classIDs in each activeX[x].xml files
activeX[x].xml.rels       – Points to individual activeX[x].bin files
activeX[x].bin                – Compound File Binary Format

Here we could modify activeX[x].xml.rels to point to the same ActiveX1.bin compound document file as normally Office creates multiple unique activeX[x].bin files. This would reduce our total file size, save some seconds at spray time and just easy to manage.

Compound File Binary Format
Using Microsoft’s Office Visualization Tool (OffVis) we can deconstruct the compound document file activeX1.bin in order to understand its structure and values. The Microsoft specifications document [3] explains everything you need to know about the format.

A compound file is a structure for storing a file system, similar to a simplified FAT file system inside a single file, by dividing the single file into sectors. It is capable of storing data that is structured as storage and streams.

Viewing our activeX1.bin file which is this case the classid is instantiating Flash. Here in the OLESSDirectoryEntry[0] section we could null out the values of the clsidThis field as when the document is opened the classid is read from our ActiveX[x].xml file. Another entry we could null out is the ModifyTime field values. One important field is Object Type. This field MUST be 0x00, 0x01, 0x02, or 0x05, depending on the actual type of object.

Unknown or unallocated   0x00
Storage Object                     0x01
Stream Object                      0x02
Root Storage Object           0x05

Non-root directory entries are normally marked as either stream or storage elements. So leaving OLESSDirectoryEntry[0] entry alone as Type 5 the other directory entries OLESSDirectoryEntry[1] OLESSDirectoryEntry[2] and OLESSDirectoryEntry[3] we could be changed to Type 0. Once Type changed to 0 the Data entry in OffVis dissappears, also SizeLow field values can then also be nulled. The SizeLow and SizeHigh fields represent the stream size (8 bytes). This 64-bit integer field contains the size of the user-defined data, if this is a stream object. For a root storage object, this field contains the size of the mini stream.

The benefit of these changes is that we can remove any unwanted data at the end and just have an ActiveX1.bin file of only 2048 bytes. As for nulling out clsidThis and ModifyTime fields just removes any reference to the classid or time modified. If we wanted to say encapsulate our sprayed data we could change the Type object value to 2 and SizeLow value as you can see below but not really necessary so no need to complicate stuff. when it comes to the spraying our data I noticed all we need to do is just append our sprayed data to our 2048 bytes compound file without making any further changes. This is enough to load it in memory.

Class IDs to use
Now the question comes to what classIDs do we use for our heap spray? ClassIDs are set in the ActiveX[x].xml files where then the associated libraries loads. After experimenting with different classids I realised any classID could be used, depending on what classID is being called affects the performance drastically.

For example exploits CVE-2013-3906 or CVE-2015-1641 used classID {1EFB6596-857C-11D1-B16A-00C0F0283628} (MSComctlLib.TabStrip.2).  This refers to library C:\Windows\system32\MSCOMCTL.OCX which is 1,070,232 bytes in size. This library is huge so the amount of time to spray accumulates on how many chunks being sprayed. So if I used a classID which referred to a library of a small file size the spray time reduced drastically. Taking it a step further, it was discovered that using a non-existing classID could be used such as {00000000-0000-0000-0000-000000000001}. Since this classID does not exist on the system there would be no referring library to load so in theory would further reduce the spray time. During tests this proved to be the case and heap spraying was successful and the time was further reduced.

The activeX[x].xml file would normally look like this

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<ax:ocx ax:classid='{00000000-0000-0000-0000-000000000001}'
ax:persistence='persistStorage' r:id='rId1'
xmlns:ax='http://schemas.microsoft.com/office/2006/activeX'
xmlns:r='http://schemas.openxmlformats.org/officeDocument/2006/relationships'/>

Heap Spraying times
To get an idea of what kind of times we are dealing with, MetaSploit’s TIFF Integer Overflow exploit [4] was used which uses ActiveX to spray the heap with 591 chunks using the classid {1EFB6596-857C-11D1-B16A-00C0F0283628} referring to MSCOMCTL.OCX library. To spray the heap it took around 1 minute 10 seconds. Now replacing the classid with {00000000-0000-0000-0000-000000000001} it took only around 6 seconds which is a huge difference.

The table below shows the times it takes to spray, memory addresses sprayed upto and memory allocated based on the number of chunks. These figures will vary but it just gives you an idea.

The size of the activeX1.bin file used on Office 2010 32bit was 514KB which takes a chunk size of 0x81000 (528384 bytes) in memory.

526,336 bytes = 2048 (header) + 1024 (block size) * 512 (no. of blocks)

Chunks Time to spray Memory spray to Memory allocated
500 5 seconds 0x16450000 300 mb
1000 10 seconds 0x28DD0000 575 mb
2000 20 seconds 0x4D3A0000 1.1 gb
4000 * 58 seconds 0x7FEB0000 2 gb

* This high number of chunks might not work and document will not properly open.

The size of the activeX1.bin file used on Office 2010 64bit was 1026KB which takes a chunk size of 0x101000 (1052672 bytes) in memory.

1,050,624 bytes = 2048 (header) + 1024 (block size) * 1024 (no. of blocks)

Chunks Time to spray Memory spray to Memory allocated
500 5 seconds 0x0000000027dc0000 583 mb
1000 12 seconds 0x000000004a2f0000 1.1 gb
2000 27 seconds 0x000000008f450000 2.1 gb
4000 120 seconds 0x0000000117910000 4 gb

Memory allocated on Windows 7 32bit with Office 2010 32bit

Memory allocated on Windows 7 64bit with Office 2010 64bit

Mitigation
Spraying the heap using classids that do not exist on the system prevents a number of mitigations. So disabling ActiveX controls in Microsoft Office via the Trust Center settings or via Office kill bit in the registry are ineffective. Only using Microsoft EMET’s heap spray mitigation would provide some protection.

Summary
To get the fastest spray possible the main points to take away is

1. Use one ActiveX1.bin compound document file
2. Use a smaller ActiveX1.bin file with more xmls calling it
3. Use a classID that doesn’t exist on the system

All my Word document spray files and perl scripts you can download from here. When creating your own documents with the scripts just extract a existing document and overwrite with the files created by the scripts.

References
[1] https://www.nccgroup.trust/uk/our-research/understanding-microsoft-word-ole-exploit-primitives
[2] https://www.blackhat.com/docs/us-15/materials/us-15-Li-Attacking-Interoperability-An-OLE-Edition.pdf [PDF]
[3] https://msdn.microsoft.com/en-gb/library/dd942138.aspx
[4] https://www.rapid7.com/db/modules/exploit/windows/fileformat/mswin_tiff_overflow

This is just a short post highlighting how easily ASLR could be bypassed by instantiating ActiveX controls using certain classids in Microsoft Office. I’ve mainly tested with MS Word on an updated Windows 7 32bit with Office 2010 32bit but other applications such as Excel and PowerPoint should work too.

All these classids listed in the below table give security warning prompt but the library will still load before any action is taken.

Library sqlceca35.dll comes with Microsoft SQL Server Compact which is an embedded database that gets installed by Microsoft Office. I’ve seen some systems with version 4.0 installed where sqlceca40.dll has its dynamic bit set and thus gets ASLRed.

C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\sqlceca35.dll
{20347534-760B-464D-B572-285E6B618257} SSCE.Error.3.5
{3018609E-CDBC-47E8-A255-809D46BAA319} SSCE.DropTableListner.3.5
{455C3E04-BFE9-4089-8622-F2464EC3FDDB} SSCE Active Sync Engine.3.5
{7C7E6C99-BB8D-4718-AAA9-70C4320010DE} SSCE.Params.3.5
{8CD1B98D-D8D5-4B51-9564-48B12A98698F} SSCE.RemoteDataAccess.3.5
{9E7E2CCE-3F1F-4891-892C-AC8B486D03B2} SSCE.Params.3.5
{9FD542D2-61C4-4E9F-A8E2-E6B8C7F64CBF} SSCE.Errors.3.5
{A9D3060D-3526-4538-B13A-1913568DAA0D} SSCE.Engine.3.5
{EA91E968-EF93-4FF1-86F3-75CC93416DF2} SSCE.Replication.3.5
C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\sqlceoledb35.dll
{90A1998A-EB21-4F61-872F-F4DFDE1065D6} Microsoft.SQLSERVER.CE.OLEDB.
ErrorLookup.3.5
C:\Program Files\Common Files\System\Ole DB\XMLRW.dll
C:\Program Files\Common Files\System\Ole DB\XMLRWBIN.dll
{10154F28-4979-4166-B114-3E7A7926C747} MSOLAP.4
{867CD778-80D7-4f93-989E-B3E76A92FB42} MSOLAP100ErrorLookup.1
C:\Windows\system32\msvbvm60.dll
{D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731}
C:\Program Files\Common Files\Microsoft Shared\Help\msitss55.dll
C:\Program Files\Common Files\Microsoft Shared\TRANSLAT\FREN\MSB1FREN.DLL
C:\Program Files\Common Files\Microsoft Shared\Help\ITIRCL55.DLL
C:\Program Files\Common Files\Microsoft Shared\TRANSLAT\ESEN\MSB1ESEN.DLL
{5591379C-B467-4BCA-B647-A438712504B0} LR.LexRefTfFunctionProvider.1.0.1
C:\Program Files\Microsoft Sync Framework\v1.0\Runtime\x86\Synchronization.dll
{A7B3B4EE-925C-4D6C-B007-A4A6A0B09143}
C:\Program Files\Microsoft Sync Framework\v1.0\Runtime\x86\FeedSync.dll
{BC0CD90A-2C24-41BE-B6EC-87C15D919418}
C:\Program Files\Common Files\Microsoft Shared\VSTA\8.0\x86\VSTARemotingServer.dll
{60A896CA-1649-45BF-B63F-2E7312A968F0}
C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Tools.Applications.Blueprints\
8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Tools.Applications.Blueprints.dll
{65C52C10-2286-420A-B35C-15CF7F9B5876} Microsoft.VisualStudio.Tools.Applications.
Blueprints.HostControl
C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Tools.Applications.DesignTime\
8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Tools.Applications.DesignTime.dll
{9DA65B6A-813C-4592-9E8A-412C40BBC4B7} Microsoft.VisualStudio.Tools.Applications.
DesignTime.HostAdapter

Some are shown to get rebased as I loaded all libraries in one go but if loaded individually the address should not change.

Taking a look in Office 2010 64bit we still see some do not get ASLRed.

Disabling ActiveX controls in Microsoft Office
Disabling ActiveX controls can be configured via the Trust Center settings

File — Options — Trust Center — Trust Center Settings — ActiveX Settings

This will disable all controls so probably not a good idea in your environment

Disabling specific embedded ActiveX controls with Office kill bit
To enable the Office COM kill bit for a specific control to block a registry key would need to be added with the CLSID of the ActiveX control then add a DWORD value of 0x00000400 to the Compatibility Flags. The location for setting the Office 2010 COM kill bit in the registry is

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Common\COM Compatibility

Microsoft EMET
Using EMET we can see all libraries get ASLRed.

Microsoft Office 2013
Finally in Office 2013 the classids that do exist, the libraries that do load have already got there dynamic bit set and get ASLRed

All the documents with these classids can be downloaded from here

A couple of months ago a RTF 0-day was used in attacks and to bypass ASLR (Address Space Layout Randomization) it was using a non-ASLR module MSCOMCTL.OCX.  This got me interested to research into how it was actually loading up and discover if there were any more modules that could be used in the future following the recent Microsoft bulletin MS14-024 that finally implemented ASLR on the module. I started with an exploit taken from MetaSploit which exploits the Microsoft Word RTF Object Confusion vulnerability (CVE-2014-1761) and patched in April updates MS14-017 . This exploit uses module MSCOMCTL.OCX to bypass ASLR and what I needed was that part of the code so removed all other code leaving it just to load the OCX file.

Just to load the OCX file we are looking around 17018 bytes added to the exploit. Far too large so I started looking into ways to reduce the size. Most of the data was used in the control word \objdata which contains the data used by the object represented in hexadecimal. Taking this data and using a vbs script I wrote the data to file so it could be easily viewed in a hex editor to try and make sense of it.

The FormatID value of 0x00000002 tells the ObjectHeader structure that it must be followed by an EmbeddedObject structure. The main value to look at was the bulk size of the data which had a size of 0x00001E00 (7680 bytes), going to the end of this data clunk leads to the next OLEVersion header. Removing this data chunk, some control words and tidying it up we are left with

As you can see I have also changed the data chunk size to 1 and the data chunk only now contains 0x41 and the file size has gone down to 1619 bytes. (Size defined on line 8)

Looking at the remaining data above there is another OLEVersion header and FormatID value. FormatID 0x00000005 tells us that the classname must be present, is this case METAFILEPICT. The classname field identifies the type of the presentation data structure and in this case is a Windows Meta File (WMF). If we change the FormatID to 0x00000000 it tells the parser that that classname field must not be present and we can remove the rest of the data chunk which leaves us with

Lastly the control word \objclass is optional so thats removed

Finally we end up with a size of 180 bytes from the huge 17018 bytes we started in the beginning. It could be the 0-day exploit chose a large chunk of object data to give it a bit of size and confusion for the analyst when reverse engineering the RTF. A good Microsoft document  “Object Linking and Embedding (OLE) Data Structures”  explains the data structures.

Searching for new ActiveX/COM objects
Now that all the irrelevant data had been discarded it was a matter of just changing the ProgID (programmatic identifier) and size of the ProgID. Since ActiveX controls are not being used in Internet Explorer the controls are not required to be marked as “safe for initialization” or “safe for scripting”. The tedious task now was building a couple of vanilla Windows machines and get them all up-to-date, testing with only Windows first and then with Microsoft Office. Actions needed to take were

  • List all non ASLR modules
  • List all COM object modules
  • Test modules can be loaded in Word
  • Check modules does not get rebased

After going through this process I ended up with two libraries that fitted the criteria perfectly.

Library OTKLOADR.DLL
Path C:\Program Files\Microsoft Office\Office14\ADDINS\
C:\Program Files (x86)\Microsoft Office\Office14\ADDINS\ (W64)
ProgIDs otkloadr.WRAssembly.1
otkloadr.WRLoader.1
Versions 7.10.2179.0 (msvcr71.dll) 7.10.5077.0 (olkloadr.dll)
Note OTKLOADR.DLL gets rebased but is linked to another non-ASLR module MSVCR71.DLL in the same path
Library SQLCECA35.DLL
Path C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\
C:\Program Files (x86)\Microsoft SQL Server Compact Edition\v3.5 (W64)
ProgIDs SSCE.DropTableListener.3.5
SSCE.Engine.3.5SSCE.Error.3.5
SSCE.Errors.3.5
SSCE.Param.3.5
SSCE.Params.3.5
SSCE.RemoteDataAccess.3.5
SSCE.Replication.3.5
Versions 3.5.5692.0 (sqlceca35.dll and sqlceer35EN.dll)
Note Another module also gets loaded sqlceer35EN.dll but gets rebased

All of the ProgIDs listed above apart from one loads the relevant non ASLR module successfully but upon exiting MS Word it prompts “Do you want to save changes you made to {filename}” and also most of the time gives error “There is not enough memory or disk space to display or print the picture”.

The one that works with no prompts or errors was using ProgID “otkloadr.WRAssembly.1“. This ProgID works with no issues at all, opens and exits the document cleanly, no square box displayed and it happens to be our friendly old “MSVCR71.DLL” library not compiled with the /DYNAMICBASE option. Looks like this library just does not go away and has come back to haunt us again 🙂 Another research area would be to load all ProgIDs available and monitor which ones load non-ASLR modules but that’s for another day. Here is a screenshot of both libraries loaded in WINWORD.EXE process space

This has been tested on a fully patched Windows 7 SP1 Enterprise OS (32bit and 64bit) with Microsoft Office Professional Plus 2010 (32bit) with version of Word being 14.0.7116.5000 (32bit) and here is the code using ProgID otkloadr.WRAssembly.1

{\rtf1{\object\objocx{\*\objdata 
01050000
02000000
16000000
6f746b6c6f6164722e5752417373656d626c792e3100
00000000
00000000
01000000
41
01050000
00000000
}}}

Third Party modules
As I started looking at other apps dozens of ProgIDs were being discovered. ITunes and DivX player contains modules that could be loaded by their ProgIDs but unlikely as they use the preferred base address of 0x10000000 so if some module is already loaded at that address then the next module would get rebased. Yahoo Messenger contains a number of ProgIDs that does not get rebased. I also found some old Microsoft OCX files (non-ASLRed) installed on another PC most likely by other third-party software or old Microsoft software. A quick test on ProgIDs PicClip.PictureClip.1 (PICCLP32.OCX) MSMAPI.MapiMessage.1 (MSMAPI32.OCX) worked fine.

C:\Windows\System32\COMCT232.OCX   
C:\Windows\System32\COMCTL32.OCX   
C:\Windows\System32\COMDLG32.OCX   
C:\Windows\System32\MCI32.OCX
C:\Windows\System32\MSCOMCT2.OCX   
C:\Windows\System32\MSCOMM32.OCX
C:\Windows\System32\MSFLXGRD.OCX   
C:\Windows\System32\MSINET.OCX
C:\Windows\System32\MSMAPI32.OCX
C:\Windows\System32\MSMASK32.OCX
C:\Windows\System32\MSWINSCK.OCX
C:\Windows\System32\PICCLP32.OCX
C:\Windows\System32\SYSINFO.OCX
C:\Windows\System32\TABCTL32.OCX

Mitigation
The best mitigation would be to install Microsoft EMET and add MSWord (WINWORD.EXE) to its application list. EMET has a number of mitigations which will stop exploits one way or another and it’s free so there’s no excuse for not getting it deployed. There is also a  FixIT from Microsoft which configures the Microsoft Office File Block policy to prevent the opening of RTF files in supported versions of Microsoft Word. You can also configure the blocking of RTF files manually in the Trust Center settings.

File — Options — Trust Center — Trust Center Settings — File Block Settings

Make sure “Open” is checked for RTF Files. Further below there are three other choices. “Do not open selected file types” selected won’t even open the file which is what you want.

Choosing “Open selected file types in Protected View” which is the default opens another WINWORD.EXE as a child process in low integrity mode.

The registry settings are below if you decide to script it out to your managed assets.

Windows Registry Editor Version 5.00
;
[HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Word\Security\FileBlock]
"RtfFiles"=dword:00000002
"OpenInProtectedView"=dword:00000001
;
; "RtfFiles"=dword:00000001            - Save checked
; "RtfFiles"=dword:00000002            - Open and Save checked
; "OpenInProtectedView"=dword:00000000 - Do not open selected file types
; "OpenInProtectedView"=dword:00000001 - Open selected file types in Protected View
; "OpenInProtectedView"=dword:00000002 - Open selected file types in Protected View and allow editing

By default for most MSWord document formats are not set for Protected View settings so MSWord would be running in medium integrity meaning once compromised would be extremely damaging making malware persistent on the machine. RTF format file extensions .rtf can be renamed to .doc and still would be parsed as RTF so bear that in mind for those who are thinking of blocking just by .rtf extension on your mail relays.

Conclusion
Bypassing ASLR on Microsoft Word RTF formatted documents has now become a lot easier as we can see. There could be potentially hundreds of possible ProgIDs on a system from various applications that could be used increasing the ever threat of being compromised. Until all vendors start compiling there code with the /DYNAMICBASE option which I don’t see it happening anytime soon the only real defense would be to get Microsoft EMET installed on all assets ASAP.

Here is a zip file containing some example RTF files, third-party software ProgIDs, vbs script, etc.