Threat Research

Advanced Exploit Techniques Attacking the IE Script Engine

By Zhenhua 'Eric' Liu | June 15, 2014

Exploit developers should be very excited recently; lots of big bombs have been dropped to the community.

In February, Yang Yu was awarded the Microsoft mitigation bypass bounty, the top prize in Microsoft Bounty Programs. He talked about parts of his mitigation bypass in his presentation at CanSecWest 2014. However, the most interesting part - the so-called "Vital Point Strike" - was just left as blurred pages in his slides.

Soonafter, another security researcher, Yuki Chen, published ExpLib2, which is Yuki's exploitation library for Internet Explorer. It has been added to Metasploit later.

Not long after that, the famous security researcher Yuange published the technique that he calls "DVE", which he claims to have discovered several years ago.

To our understanding, the last two techniques are talking about the same thing (for Yang Yu's technique, we could only guess): attacking the less protected script interpreter engine in Microsoft Internet Explorer. By utilizing the script engine to execute malicious code, attackers could circumvent all modern memory protections except for the application sandbox.

Technical Analysis

As we know, with the introduction of modern exploit mitigation techniques such as Data Execution Prevention (DEP), Address Space Layout Randomization (ASLR), Export Address Table Access Filtering (EAF), etc., memory exploits are becoming more and more complicated. Normally, exploits need to nicely chain the following steps together: disclose the module address, build the return-oriented programming (ROP) chain, place the shellcode, control the extended instruction pointer (EIP), etc.

The advanced techniques discovered by the exploit researchers mentioned above changed the game with the following factors:

  1. Scripts could complete the same job as a shellcode.

  2. The script interpreter engine in Internet Explorer (the engine that interprets JScript and VBScript) could execute malicious scripts; all they need is an escalated privilege, a.k.a. the "God Mode" mentioned in Yang Yu's slides.

Given these two factors, we can see that it is possible for malicious activities to be executed using scripts - no shellcode needed, no need to deal with the bloated memory protections, no EIP control, etc.

And now the only question is - is the script interpreter engine in Internet Explorer safe enough?

The answer is obviously 'No'. In fact, the safety of the IE script engine relies solely on one single byte - the SafetyOption flag.

Two functions, COleScript::CanCreateObject and COleScript::CanObjectRun, perform separate checks on the SafetyOption flag in order to decide if it is safe to create and run the ActiveX object.

The following is the check performed in the COleScript::CanCreateObject function.

IEScriptEngine 0

Figure 1. SafetyOption flag check in COleScript::CanCreateObject in jscript.dll 5.8.

The following is the check performed in the COleScript::CanObjectRun function.

IEScriptEngine 1 1

Figure 2. SafetyOption flag check in COleScript::CanObjectRun in jscript.dll 5.8.

Simply modifying this flag to 0 or 4 in JScript or modifying it to 0 in VBScript could enable the "God Mode".

But in order to do this, the attacker first needs to know the memory address of this flag and then utilize an arbitrary write bug. With the appeal of array/vector object modification techniques, more zero-day vulnerabilities could turn into full process memory access, such as demonstrated with CVE-2013-0643, CVE-2013-1690, CVE-2013-3163, CVE-2014-0322, CVE-2014-1776, etc.

Once full process memory access has been acquired, the SafetyOption flag could easily be modified.

Below is the exploitation process:

   Step 0: Exploit a use-after-free bug.

   Step 1: Perform an arbitrary address write (allow the attacker to modify one byte).

   Step 2: Implement an array/vector object modification technique (which will give full process memory access).

   Step 3: Modify the SafetyOption flag of the IE script engine (to enable "God Mode").

   Step 4: Execute the privileged script (a.k.a., Do evil things).

In my opinion, having this full process memory access ability is already in "Super Mode". The exploit could then just choose to use ROP/shellcode techniques, which is the traditional way (and might be mitigated or detected by current APT protections), or the privileged script execution way. The core value of the latter is in the countermeasures; it is difficult for APT detection products to detect this behavior.

Protection in IE 11

In Internet Explorer 11, VBScript remains the same; modifying the SafetyOption flag to 0 still works fine.

The story changed in the JScript engine; some protection has now been added to this flag.

In this version of IE, a 0x20-byte hash value has been introduced. Whenever the SafetyOption flag is used, the function ScriptEngine::GetSafetyOptions is called to generate a new hash that is then compared with the original hash value, which is stored in memory. A fast fail is triggered if this check is not successful, and the process is terminated.

IEScriptEngine 2

Figure 2. Checking the calculated SafetyOption hash against the stored hash.

As we can see in Figure 2 above, the SafetyOption flag is stored in obj_ScriptEngine + 0x1F0. This value is then passed to the function ScriptEngine::GenerateSafetyOptionHash and the result is compared with the original hash value, which is stored in obj_ScriptEngine + 0x1F4.

The figure below shows how the calculation in ScriptEngine::GenerateSafetyOptionHash is done.

IEScriptEngine 3

Figure 3. The GenerateSafetyOptionsHash function.

We can see here that the hash value is calculated from the base address of the Script Engine object, the SafetyOption flag, and some random data. Modifying any of these via memory corruption bugs would result in a different hash, which would then forbid the creation of the script object.

The awkward thing here is that the decision to enable "God Mode" still relies on the result of the functions ScriptEngine::CanCreateObject and ScriptEngine::CanObjectRun. As long as these functions return non-zero, the "God Mode" will still be enabled in IE 11 JScript. Yes, setting the SafetyOption flag (the obvious shortcut), will no longer return a non-zero value, but there are still other ways of doing it, such as modifying the application data in the ScriptEngine object, which are still not protected.

This was demonstrated by Yuki Chen's ExpLib2, where he just replaced the security manager of the Script Engine object, which is at offset 0x21C, to point to a fake virtual function table (vftable). This fake vftable points to a table of function pointers, two of which are the pointers to the functions MSHTML!TearoffThunk4 and MSHTML!TearoffThunk5. These pointers have been changed to point to hijacked versions of MSHTML!TearoffThunk4 and MSHTML!TearoffThunk5, which both force the ScriptEngine::CanCreateObject and ScriptEngine::CanObjectRun to return non-zero.

The figure below shows what the Script Engine object looks like before modification.

IEScriptEngine 4

Figure 4. The normal Script Engine object.

Here is what the Script Engine object looks like after the security manager has been modified by ExpLib2.

IEScriptEngine 5

Figure 5. The modified Script Engine object.

After this modification, the functions ScriptEngine::CanCreateObject and ScriptEngine::CanObjectRun will always return a non-zero value, enabling the "God Mode". Excellent job!


Thanks to these outstanding security researchers, we can see how easy it is to bypass modern mitigations using one technique. Since the only prerequisite for using this is a vulnerability for an arbitrary write (which is common nowadays), we can anticipate more zero-days that will use this technique in the near future.

Because of the fact that some vulnerabilities could easily turn into full process memory access, some existing security mechanisms should be reconsidered. In my opinion, here are a few ideas that the software vendor can do to make IE safer:

  1. Consider abandoning VBScript in Internet Explorer. IE 11 edge mode no longer supports VBScript in the Internet zone which is the right way to go.

  2. Consider improving the security of the JScript Engine in Internet Explorer, such as protecting the member data in the object and disabling some privileged methods.

  3. Consider implementing protection for application data in JScript arrays and VBScript arrays, at least encoding the length field. This can also apply to JAVA arrays and Adobe flash vectors.

  4. Consider implementing randomization in the IE custom heap management.

In the meantime, we expect more zero-days to come out that exploit this weakness. With Fortinet's global threat monitoring and research team here, we will always be there on the front lines when that happens and will make sure to protect our customers from these attacks.

Special Contribution by Margarette Joven

Join the Discussion