The King is dead. Long live the King! Root cause analysis of the latest Internet Explorer zero day – CVE-2018-8174

In late April 2018, a new zero-day vulnerability for Internet Explorer (IE) was found using our sandbox; more than two years since the last in the wild example (CVE-2016-0189). This particular vulnerability and subsequent exploit are interesting for many reasons. The following article will examine the core reasons behind the latest vulnerability, CVE-2018-8174.

Searching for the zero day

Our story begins on VirusTotal (VT), where someone uploaded an interesting exploit on April 18, 2018. This exploit was detected by several AV vendors including Kaspersky, specifically by our generic heuristic logic for some older Microsoft Word exploits.

After the malicious sample was processed in our sandbox system, we noticed that a fully patched version of Microsoft Word was successfully exploited. From this point we began a deeper analysis of the exploit. Let’s take a look at the full infection chain:

The infection chain consists of the following steps:

A victim receives a malicious Microsoft Word document.

After opening the malicious document, a second stage of the exploit is downloaded; an HTML page containing VBScript code.

The VBScript code triggers a Use After Free (UAF) vulnerability and executes shellcode.

Initial analysis

We’ll start our analysis with the initial Rich Text Format (RTF) document, that was used to deliver the actual exploit for IE. It only contains one object, and its contents are obfuscated using a known obfuscation technique we call “nibble drop“.

After deobfuscation and hex-decoding of the object data, we can see that this is an OLE object that contains a URL Moniker CLSID. Because of this, the exploit initially resembles an older vulnerability leveraging the Microsoft HTA handler (CVE-2017-0199).

With the CVE-2017-0199 vulnerability, Word tries to execute the file with the default file handler based on its attributes; the Content-Type HTTP header in the server’s response being one of them. Because the default handler for the “application/hta” Content-Type is mshta.exe,it is chosen as the OLE server to run the script unrestricted. This allows an attacker to directly call ShellExecute and launch a payload of their choice.

However, if we follow the embedded URL in the latest exploit, we can see that the content type in the server’s response is not “application/hta”, which was a requirement for CVE-2017-0199 exploitation, but rather “text/html”. The default OLE server for “text/html” is mshtml.dll, which is a library that contains the engine, behind Internet Explorer.

Furthermore, the page contains VBScript, which is loaded with a safemode flag set to its default value, ‘0xE’. Because this disallows an attacker from directly executing a payload, as was the case with the HTA handler, an Internet Explorer exploit is needed to overcome that.

Using a URL moniker like that to load a remote web page is possible, because Microsoft’s patch for Moniker-related vulnerabilities (CVE-2017-0199, CVE-2017-8570 and CVE-2017-8759) introduced an activation filter, which allows applications to specify which COM objects are restricted from instantiating at runtime.

At the time of this analysis, the list of filtered CLSIDs consisted of 16 entries. TheMSHTML CLSID ({{25336920-03F9-11CF-8FD0-00AA00686F13}}) is not in the list, which is why the MSHTML COM server is successfully created in Word context.

This is where it becomes interesting. Despite a Word document being the initial attack vector, the vulnerability is actually in VBScript, not in Microsoft Word. This is the first time we’ve seen a URL Moniker used to load an IE exploit, and we believe this technique will be used heavily by malware authors in the future. This technique allows one to load and render a web page using the IE engine, even if default browser on a victim’s machine is set to something different.

The VBScript in the downloaded HTML page contains both function names and integer values that are obfuscated.

Vulnerability root cause analysis

For the root cause analysis we only need to look at the first function (‘TriggerVuln’) in the deobfuscated version which is called right after ‘RandomizeValues’ and ‘CookieCheck’.

To achieve the desired heap layout and to guarantee that the freed class object memory will be reused with the ‘ClassToReuse’ object, the exploit allocates some class objects. To trigger the vulnerability this code could be minimized to the following proof-of-concept (PoC):

When we then launch this PoC in Internet Explorer with page heap enabled we can observe a crash at the OLEAUT32!VariantClear function.

With this PoC we were able to trigger a Use-after-free vulnerability; both ArrA(1) and ArrB(1) were referencing the same ‘ClassVuln’ object in memory. This is possible because when “Erase ArrA” is called, the vbscript!VbsErase function determines that the type of the object to delete is a SafeArray, and then calls OLEAUT32!SafeArrayDestroy.

It checks that the pointer to a tagSafeArray structure is not NULL and that its reference count, stored in the cLocks field is zero, and then continues to call ReleaseResources.

ReleaseResources, in turn will check the fFeatures flags variable, and since we have an array of VARIANTs, it will subsequently call VariantClear; a function that iterates each member of an array and performs the necessary deinitialization and calls the relevant class destructor if necessary. In this case, VBScriptClass::Release is called to destroy the object correctly and handle destructors like Class_Terminate, since the VARTYPE of ArrA(1) is VT_DISPATCH.

This ends up being the root cause of the vulnerability. Inside the VBScriptClass::Release function, the reference count is checked only once, at the beginning of the function. Even though it can be (and actually is, in the PoC) incremented in an overloaded TerminateClass function, no checks will be made before finally freeing the class object.

Class_Terminate is a deprecated method, now replaced by the ‘Finalize’ procedure. It is used to free acquired resources during object destruction and is executed as soon as object is set to nothing and there are no more references to that object. In our case, the Class_Terminate method is overloaded, and when a call to VBScriptClass::TerminateClass is made, it is dispatched to the overloaded method instead. Inside of that overloaded method, another reference is created to the ArrA(1) member. At this point ArrB(1) references ArrA(1), which holds a soon to be freed ClassVuln object.



After the Class_Terminate sub is finished, the object at ArrA(1) is freed, but ArrB(1) still maintains a reference to that freed class object. When the execution continues, and ArrB is erased, the whole cycle repeats, except that this time, ArrB(1) is referencing a freed ClassVuln object, and so we observe a crash when one of the virtual methods in the ClassVuln vtable is called.

Conclusion

In this write up we analyzed the core reasons behind CVE-2018-8174, a particularly interesting Use-After-Free vulnerability that was possible due to incorrect object lifetime handling in the Class_Terminate VBScript method. The exploitation process is different from what we’ve seen in exploits for older vulnerabilities (CVE-2016-0189 and CVE-2014-6332) as the Godmode technique is no longer used. The full exploitation chain is as interesting as the vulnerability itself, but is out of scope of this article.

With CVE-2018-8174 being the first public exploit to use a URL moniker to load an IE exploit in Word, we believe that this technique, unless fixed, will be heavily abused by attackers in the future, as It allows you force IE to load ignoring the default browser settings on a victim’s system.

We expect this vulnerability to become one of the most exploited in the near future, as it won’t be long until exploit kit authors start abusing it in both drive-by (via browser) and spear-phishing (via document) campaigns. To stay protected, we recommend applying latest security updates, and using a security solution with behavior detection capabilities.

In our opinion this is the same exploit which Qihoo360 Core Security Team called “Double Kill” in their recent publication. While this exploit is not limited to browser exploitation, it was reported as an IE zero day, which caused certain confusion in the security community.

After finding this exploit we immediately shared the relevant information with Microsoft and they confirmed that it is in fact CVE-2018-8174, and received an acknowledgement for the report.

This exploit was found in the wild and was used by an APT actor. More information about that APT actor and usage of the exploit is available to customers of Kaspersky Intelligence Reporting Service. Contact: intelreports@kaspersky.com

Detection

Kaspersky Lab products successfully detect and block all stages of the exploitation chain and payload with the following verdicts:

HEUR:Exploit.MSOffice.Generic – RTF document

PDM:Exploit.Win32.Generic – IE exploit – detection with Automatic Exploit Prevention technology

HEUR:Exploit.Script.Generic – IE exploit

HEUR:Trojan.Win32.Generic – Payload

IOCs