Do You Want To Build A Snowman?
In case you haven’t already heard the news, Google and Adobe just killed a popular information leak technique in the most recent version of Flash (v220.127.116.11). Mozilla went so far as to block Flash entirely. This was hot on the tails of two previously unknown, unpatched (0day) vulnerabilities in Flash, which were publicly disclosed as part of the enormous reams of information stolen from Hacking Team.
Flash has been a popular target with attackers for a long time, and news of yet more exploitable vulnerabilities shouldn’t come as a surprise. That is not to say these efforts aren’t laudable, as anything that raises the bar for attackers is good, but let’s put things in perspective for a moment.
In recent weeks, I’ve been digging through vulnerabilities and exploits published over the past couple of years looking for ways I might improve upon the original exploit. Developing any skill requires practice and software exploitation is no different. One of the vulnerabilities I settled on was CVE-2014-0322 (MS14-012), a use-after-free vulnerability in Internet Explorer (IE). I wanted to challenge myself to develop an information leak using only the original vulnerability with no external dependencies.
It turns out this thought exercise was a bit serendipitous as it so happens the technique that Google and Adobe recently fixed was used in the original exploit for CVE-2014-0322. While Flash was not the vulnerable software, in this case, it did enable exploitation of the IE flaw. This is not an uncommon scenario -- some piece of software that integrates with your browser reduces its overall security. We’ve seen this scenario play out with Office, Java, Flash and a myriad of other lesser-known browser plugins.
Sometimes exploit developers can become a bit myopic with regards to techniques, or at least browsing exploit-db would lead me to believe that. The aforementioned Flash technique has been used in a number of exploits with a great deal of success. However, the mitigation is fairly simple: disable Flash. In the case of a vulnerability where Flash simply made exploitation of the flaw easier but was not the target of the exploit itself, this will absolutely cripple the exploit.
The reliance on external software components to successfully exploit a vulnerability is a bit of an epidemic at this point. While there have been a number of presentations, papers and blog posts on how to better exploit certain classes of vulnerabilities, it seems like we, as researchers, rarely do, at least publicly.
Let’s take a look at some Metasploit modules for browser-based memory corruption vulnerabilities over the past three years. For the sake of brevity, I have decided to focus on 32-bit targets (the lack of 64-bit targets is a whole other discussion) and desktop OS versions as this is the case for most public browser exploits.
I primarily want to focus on the far right column. There are almost no targets for modern Windows versions in conjunction with IE versions 8 and higher that do not rely on some external component. While I am certain they are all effective in their own right, I am not sure all of these exploits fully demonstrate a worst case scenario for a defender. There is a good chance a number of these vulnerabilities are exploitable in the absence of any external components, despite the fact that developing an exploit without them is probably much more difficult.
A lot of people have warned us that the “application specific”] or “information leak” era of exploitation was on the horizon. Suffice it to say, that era has arrived and, by and large, this is a good thing and it means our countermeasures are working. There is little doubt that exploiting certain classes of vulnerabilities is becoming increasingly more difficult.
The key to exploiting most vulnerabilities in the face of modern countermeasures is to find an information leak vulnerability or use a different vulnerability to create one. If you are able to read the contents of an application’s memory, it is often game over for many mitigations currently in use.
I am going to go out on a limb and say information leaks (or methods to create them) are becoming the premier bug class. A great deal of research has been published about finding and creating information leaks to aid in exploitation, but their actual adoption in public exploits appears limited.
For those not already aware, the recently patched Flash technique relies on an attacker filling the heap with Vector objects and subsequently corrupting the size of a Vector at a predictable location. By increasing the Vector’s size with a memory corruption flaw, the attacker is able to access memory contents outside of the Vector’s intended bounds. This can be used as an oracle into the application’s memory layout to defeat countermeasures like ASLR. Full details of the recent mitigations and a more detailed explanation of this technique can be found here.
The Flash Vector length overwrite has been used in a number of pure Flash exploits and to assist in the exploitation of other software like IE. This was the case for CVE-2014-0322 as it was discovered in the wild. If you can implement an exploit without external dependencies, this is generally the ideal scenario. Why implement an exploit that depends on external resources when you can write a better one that doesn’t? With that in mind, I decided that it might be worth sharing an alternate approach to obtaining an information leak using this vulnerability.
Short Customer Story: CVE-2014-0322
The details of the vulnerability itself have been covered elsewhere, so for the sake of brevity, I am not going to go into a lot of depth here. The vulnerability is a use-after-free (UAF) flaw affecting IE 10. The vulnerability was discovered being exploited in the wild as part of “Operation Snowman” (my Duo Security attribution ball is coming up ‘teenager’) and the exploit leveraged Adobe Flash to implement an information leak in order to bypass DEP, ASLR, and subsequently gain arbitrary code execution. Disabling Flash obviously renders the exploit ineffective. However, there is always another way.
Thinking in Primitives
To get a good handle on software exploitation, the first thing you learn to do is think in primitives. What kind of control does a vulnerability provide and how can an attacker leverage it? More interesting than the root cause of the vulnerability itself is the primitive it gives us. A large portion of browser UAF vulnerabilities result in the attacker being able to hijack a free()’d object’s vftable. This generally leads to arbitrary code execution when a vfpointer the attacker has taken control of is dereferenced.
Instead of controlling a vfpointer, CVE-2014-0322 provides us with a powerful increment primitive. This gives us a great deal of flexibility to craft a very robust exploit.
As we control the contents of the eax register at the time of the crash, we can increment the value at any writeable address. This gives us a lot of flexibility to manipulate the contents of memory to our advantage. A few of the things an attacker might consider doing are:
- Change an inline structure size (like the aforementioned Flash Vector attack)
- Modify heap metadata structures (mark busy chunks free, etc.)
- Modify a pointer or return address (change execution flow)
- Overflow a reference count (cause an object to go out of scope)
- Increment the null byte at the end of a C string (leak the data behind the string)
- Toggle some security feature on or off (like a bytecode verifier)
- Toggle an authentication or privilege flag (elevate our privileges)
Obviously not all of these make sense in the context of this vulnerability, but the point is, you have to work with what you’ve got. However, in this case ‘what we’ve got’ is a lot of possibilities.
Since the goal was to build an information leak, we want to target something that will provide us insight into the contents of IE’s heap memory. As I mentioned previously, the original exploit did this by modifying the size of a Flash Vector and subsequently causing an out of bounds read to disclose memory. To do something similar purely in IE, we have a couple of obvious options (although we are certainly not limited to any of them):
- Increment a BSTR length or null terminator
- Use the UAF to replace our object with a different object (type confusion)
Crafting the Leak
After debating a number of possible techniques, I went with Yang Yu’s Array Object spray technique. Heap base ASLR and heap non-determinism are not a problem due to the use of a custom heap allocator in jscript9 (introduced in IE 10). As you can see from the following IDA screenshot, it is not too hard to identify. Custom allocators are often advantageous to attackers because they are rarely implemented with security considerations in mind.
I should also note that this particular technique is surprisingly fast thanks to the fact it does not rely on things like large string operations as with many BSTR based heap sprays. As such, it is likely to be highly effective in a real-world exploit when compared to many slower alternatives.
After the spray is complete the resulting memory layout provides us with a large contiguous block of Array Objects:
Using our increment primitive, we are able to increase the size value of an entry located at a predictable address (I chose 0x14141428).
Now all that’s left is to locate the modified object within the array and read back its string data. In this case, it’s quite easy since the corrupted object is the only entry with a string that does not have the value ‘AA’:
Upon reading that string we’ll get something that looks like this:
Yes, it really is that simple. Admittedly there is more work to be done to turn this into a fully fledged exploit, but a reliable information leak is the first step. At this point, I would like to note that while I did go about obtaining an information leak differently than the original exploit, I was not the first to apply this technique to this vulnerability (act surprised!). I stumbled over this full featured exploit while doing some additional research for this post.
The recent improvements to Flash are a welcome security enhancement and disabling any additional functionality is a great way to reduce your overall attack surface. Flash has certainly provided more than its fair share of vulnerabilities (I personally believe HTML5 can’t put the knife in it fast enough) and it has also enabled the exploitation of several more, but be careful to not point the finger at any particular vendor or piece of software entirely. Always be wary of what is publicly available and what the ‘state-of-the-art’ really is. A couple hours slugging it out in a debugger coupled with publicly-available techniques and I was able to build an information leak that did not require Flash.
Adept attackers will often go the extra mile to make sure their exploit works under the most minimal conditions. As defenders, we should be doing the same; just because an exploit doesn’t currently work in a chosen environment doesn’t mean it can’t. Disabling problematic software obviously reduces our attack surface, but browsers are complicated pieces of software - let’s not lure ourselves into a false sense of security. We have a very long way to go and hopefully customer stories like this one should serve as a reminder that public exploits rarely represent the state-of-the-art when it comes to attacker capabilities.
Duo Access customers will notice that we have provided the ability to identify Java and Flash plugins on end points using the service, which can be a helpful tool for administrators. In addition, mitigation technology such as Microsoft’s Enhanced Mitigation Experience Toolkit (EMET) is highly effective at mitigating most off-the-shelf exploits.
- Significant Flash exploit mitigations are live in v18.104.22.168
- Mozilla Kills Flash On Firefox As Adobe Rushes Patch
- Microsoft Security Advisory 2934088
- Operation SnowMan: DeputyDog Actor Compromises US Veterans of Foreign Wars Website
- CVE-2014-0322 "Snowman" exploit
- The Art of Leaks the Return of Heap Spraying
- CVE-2014-0322 (MS14-012) exploit
- Proof of Concept