May 16, 2018 | Posted in Blue Teams and Purple Teams by Tyler Frederick

 

Another Day, Another Microsoft Office Exploit

CVE-2018-8174, also known as “Double Kill”, is the newest in a family of exploits that leverage Microsoft Office’s OLE (Object Linking and Embedding) functionality. This particular attack uses an Office document with an embedded OLE object to directly call the Windows MSHTML engine, bypassing the user’s browser preference and some of the security controls present in a full browser session. This allows the OLE object to download a web page containing custom VBScript and immediately run it. The script takes advantage of a use-before-free vulnerability in the VBScript engine to execute arbitrary shellcode in the context of the original user.

While Microsoft has release patches to address this specific VBScript vulnerability, they continue to leave the Office OLE delivery method wide open to future exploitation. Thankfully, beginning with build 1703 of Office 365, Microsoft has included a method to block the instantiation of specific OLE objects on the basis of COM class they reference. Since all of the locally-delivered variants of this attack rely calling the MSHTML engine, blacklisting its COM class GUID is an effective method to prevent future attacks from leveraging this delivery method.

Implementing this block is as simple as creating a few registry keys. To get started, head on over to:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Office\16.0\Common\COM Compatibility

…and create a subkey called {79EAC9E0-BAF9-11CE-8C82-00AA004BA90B} which is the GUID for the MSHTML COM class. If you’re using a 32-bit Office installation on a 64-bit OS, you’ll need to hit up the registry’s Wow6432Node instead. Once that’s done, just create a DWORD value underneath that key with the name, “ActivationFilterOverride” and the value “0”. Once that’s in place, any OLE objects with a matching COM class won’t even be loaded by Microsoft Office. This mitigation, which can be used to block instantiation of other COM classes as well, carries a few caveats, so be sure to check out the rest of the article for full details.

 

Anatomy of a Hack

This attack begins with any Microsoft Office document containing an embedded OLE object. OLE was designed as a method for embedding or referencing content from one document in another. Originally making use of DDE to facilitate this embedding, OLE has been extended to support COM, Microsoft’s proprietary ABI for inter-process communication. In order to render a COM-based OLE object, the rendering application has to know what to do with the content. In much the same way as a web server specifies a MIME type so that client browsers can select an appropriate handler, OLE objects specify a COM class so that client applications know how to properly render them.

Each COM class is identified by a CLSID, a unique 128-bit GUID, which Windows stores in the registry. COM uses this CLSID, at the request of a client, to associate specific data with the DLL or EXE containing the code that implements the class, thus creating an instance of the object. Taking a look at the object data in one commonly available sample (an RTF file, after some de-obfuscation), we can spot what appears to be a CLSID located near the target URI: {79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}

A quick search through our local system’s registry reveals this CLSID listed in the registered COM classes, with a data type of URL Moniker. This particular COM class renders a specified web page directly through mshtml.dll, the rendering engine behind Internet Explorer, Windows Forms, and WPF. When the document is first opened and the OLE object is instantiated, mshtml will reach out to the URL specified with a standard GET request to retrieve the contents.

Once retrieved, mshtml proceeds to render the web page as it would normally, parsing html, CSS, and most importantly, scripts. Yep, that’s right – scripts. Due to the method by which the request is passed to mshtml, the normal security configurations present in most browsers that prevent scripts from automatically running are bypassed, allowing scripts from the target page to execute freely.

The exploit itself is a use-after-free vulnerability in the VBscript engine that occurs as a result of improper object lifetime handling in the Class_Terminate method. Since scripts can freely execute on the source web page, triggering the exploit is as trivial as simply including a <script> block in the page body. The specific mechanics involved here have been discussed quite thoroughly by various security research groups, especially Kaspersky Lab’s write-up, but the end result allows for an attacker to execute arbitrary shell on the client machine with the original user’s permissions.

 

It’s Macros All Over Again

Despite being distinctly different, embedded OLE objects have quite a bit in common with macros. They both are essentially binary code living in a document, they both allow for embedding rich interactive content, and they both work without the need for a client plugin. From a security perspective however, these two technologies diverge significantly when it comes to how and when the content is allowed to run. With recent versions of Office, Microsoft has enforced fairly strict policies on Macros: dedicated file formats (e.g. docm, xlsm), bright-yellow “here be dragons” warning bars, and most importantly, a disabled-by-default execution policy for all Macro content. Looking back on the long and arduous battle between security and user-experience around these documents, these simple changes have proven to be the single greatest victory for security.

Unfortunately, the same can’t be said for OLE content, which still enjoys a mostly carefree, “run whenever and whenever” policy, with little or no notification to the user. In spite of the continued threat it poses, Microsoft’s response to OLE content has largely been to state that the technology is a feature that’s working as expected, and not a major security loophole that needs to be addressed. Although they have released a steady stream of patches to address related vulnerabilities – such as this use-after-free vulnerability – as long as OLE can readily be leveraged as a delivery mechanism, exploits against Windows components will continue to be disseminated through Office documents.

 

So What Now?

In spite of their rather laissez faire attitude regarding OLE, Microsoft has been nice enough recently to grant us some small concessions when it comes to controlling OLE execution. Starting with build 1703 of Office 365, and likely as a direct result of previous OLE-based attacks, they quietly introduced a set of registry keys that can be used to ability to selectively block OLE/COM objects on the basis of their CLSID, as well as a default blacklist that includes HTA content and directly-embedded scripts. These keys are described in detail in this Microsoft support article.

How does this help us? Since we have the CLSID of the object used in this attack, and the ability to block COM objects by CLSID, it’s easy to roll our own mitigation strategy that’s not tied to this specific VBScript exploit. This allows for protecting against other vulnerabilities, accessible through mshtml, that could potentially be lying in wait. Thankfully, putting this mitigation in practice is fairly straightforward.

First, head on over to the COM Compatibility registry keys. For 64-bit Office installations and 32-bit Office installations on a 32-bit OS, the keys are located here:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Office\16.0\Common\COM Compatibility

And for 32-bit Office installations on 64-bit OS, they’re located here:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Office\16.0\Common\COM Compatibility

As you can see, each individual COM class has its own subkey underneath COM Compatibility. A component’s activation is controlled by the value of the ActivationFilterOverride value. When this value is set to 1, the component in question is allowed to run, and likewise, when set to 0, it is blocked. As a side note, if a key named with the component’s GUID doesn’t exist, the component is allowed to run. Likewise, if the ActivationFilterOverride value is missing, it’s interpreted the same as if it were there and set to 0, resulting in the component being blocked.

To implement a block for mshtml using this method, create a registry subkey under COM Compatibility called {79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}. Once that’s in place, create a new DWORD with the name “ActivationFilterOverride” and the value “0”. The changes take effect immediately, and can be tested by opening a document with an embedded OLE object using this class – the object shouldn’t load or reach out.

There are two important caveats to keep in mind when implementing this:

First, remember that this isn’t a replacement for installing the proper patches, it’s merely an additional layer of security. Many of the exploits delivered through OLE/COM target Windows components that are accessible from other vectors, such as this VBScript exploit which can be triggered directly from a web browser. Always ensure you systems are up-to-date with the latest patches from the manufacturer.

Second, this list is routinely overwritten during Office upgrades, as described in this Microsoft support article, so you’ll need to use a method to ensure your modifications stay in place over time. The best method to achieve this is going to vary by environment, but Group Policy is a great choice here, as you can define all the values to be updated and it will run each time policy processing runs.

This method isn’t limited to blocking the specific COM class used in this attack, however. Any valid COM class can be selectively deactivated (or activated, if it’s already on the blacklist). Although it’s still a long way from the ideal state of all OLE content being disabled by default, the ability to have any control over what content is allowed to run is a huge step in the right direction.