Hello, this is Rob Hensing. I work with the SWI team at Microsoft. One focus of my job is looking for mitigations and workarounds that we can use to protect our customers against vulnerabilities and exploits. Part of this involves testing out the mitigation technologies that we’ve baked into a lot of our products as part of the SDL process, such as buffer overflow protection like /GS, execution prevention via DEP, and address space randomization via ASLR. As a result, I spend a lot of time studying responsibly (and irresponsibly) disclosed vulnerabilities in a debugger and looking for crazy things our customers can do to protect themselves from attempts to exploit those vulnerabilities. Something that has been on my mind a lot lately is the battle for the browser and the attack surface the browser represents to the average user. And what I really mean is the battle for control of your PC by bad guys via your browser. J Obviously this is nothing new, bad guys have been pwning average users’ PCs for years using browsers, but things are about to change and I wanted to share some of my thoughts on this.
The battle for the browser was thrust into the limelight (again) this year by Shane Macaulay at CanSecWest when on Day 3 of the pwn2own festivities he and another researcher, Alexander Sotirov, were successfully able to claim the prize for pwning the Vista box using an Adobe Flash 0-day vulnerability. I was pretty sure it would be over within minutes, and when it wasn’t, I found myself checking in on their progress throughout the day. The reason I thought it would be over in minutes, is that because once you have some buggy AX control with a vulnerability running inside of IE, since about 2004, it has been almost trivial to code up a reliable exploit for it that makes use of a technique known as Heap Spray (pioneered AFAIK by Skylined), which requires nothing more than some clever JavaScript used to prepare the process’s memory to make exploitation of vulnerabilities more reliable.
You may recall that Sotirov is someone who did even more work in the area of heap spray, culminating in presentations at BlackHat on “Heap Feng Shui” and a JavaScript library that makes exploit development using heap spray even easier. But to my surprise, instead of taking minutes, it took the better part of a day before the judges declared them the winners. (In fact it took so long that I didn’t even get to see them win, as I was busy presenting on targeted attacks in one of the final sessions of the last day!). For some reason, throughout the day the exploit wasn’t working properly and IE was just crashing instead of running the shellcode. At the time, the working theory was that in Vista SP1 we must have marked the heap pages as non-executable or more accurately, Vista SP1 started enforcing no execution of instructions out of pages of memory that were not marked as executable via a concept known as DEP (Data Execution Prevention). However, this was not the case – IE7 on XPSP2 and Vista SP0/SP1 does not ”opt-in” to DEP (…yet, and more on that later). More intriguing (to me) was that, operating on the assumption that they were up against DEP, Macaulay and Sotirov set off trying to bypass DEP protection using another technique, which I don’t think was the one discussed by Skape and Skywing in this Uninformed article.
During the day, the use of a Java VM was mentioned, so I’m guessing that instead of using JavaScript to do the heap spray, Macaulay and Sotirov may have used a Java class file and a Java VM to spray memory with NOPs and shellcode. The difference? Our JavaScript library will allocate heap memory pages with PAGE_READWRITE protection (and so attempts to execute code from them can be stopped by enabling DEP) and a Java VM may allocate memory as PAGEEXECUTE_READWRITE (rendering DEP powerless to stop code execution, since the pages are marked as being intended for code execution!). Clever. _If that’s what indeed happened. (I don’t know for sure – I’m only speculating).
So why did this under-reported piece of information grab my attention? There were two reasons:
1. The fact that the researchers went after Adobe and found a code execution vulnerability is a big deal. Flash is a cross-platform application and is more ubiquitous than even IE or Windows. It is virtually guaranteed that Flash will be installed on a given machine connected to the Internet.
2. It demonstrated that researchers (and more than likely, malware or exploit writers) are actively looking for ways to bypass DEP, should it be enabled for the process they are trying to exploit.
Today, IE doesn’t use DEP by default and it would seem that researchers are already looking for ways to bypass it, anticipating a day when it might. Right now, you can make IE use DEP by following the instructions in Mike Howard’s blog (or by using the .REG file at the end of my blog post on DEP in Vista), but I suspect the vast majority of people haven’t done that and so there hasn’t been a lot of focus on bypassing DEP because there hasn’t really been the need. So why not create that need? Why haven’t we made more effort to make IE use DEP by default? For the same reason we do most things that seem counterintuitive, for application compatibility reasons. J We haven’t made IE use DEP by default yet, because it’s only in the last year or so that major 3rd party AX controls like Flash were able to run in a process using DEP without crashing the process! Remember, it was only a couple of weeks ago that Apple released an update to QuickTime that finally allows some of the key QuickTime libraries to use DEP and ASLR on Windows (which was is a very big deal!). Oh and for the record, that ”someday when IE might use DEP by default” I mentioned earlier is coming soon! In fact, recently Eric Lawrence (an IE Program Manager) went on record last week as saying that IE8 will opt-in to DEP by default on Vista using a new API that we made available in Vista SP1!
In more signs of the times: just this week, Mark Dowd, an Aussie security researcher with IBM-ISS rocked the security researcher world and blew a lot of minds with his pretty impressive work exploiting yet another Flash vulnerability (Ptacek’s write-up is a great summary if you don’t want to read the 25 page write-up from Mark). In essence, Mark found a vulnerability in Flash that allowed him to perform an arbitrary 4-byte write to a location in memory. That in and of itself isn’t necessarily what’s interesting; what’s interesting is the way he chose to leverage that vulnerability (by patching some bytes used by the ActionScript Virtual Machine, which allowed him to run dangerous ActionScript bytecode to eventually overwrite a return address on the stack, which then jumped to his x86 machine code)–which has possibly blown the doors wide open for bad guys who want reliable exploitation techniques that don’t involve the traditional Javascript heap spray approach. Mark mentions in his paper that his exploit worked reliably on Vista because Adobe didn’t opt-in to ASLR with the core Flash binary (which on my machine is flash9f.ocx, the most recent version that contains the fix for the vulnerability discovered by Mark). It turns out that the 4-byte write that Mark uses to “get things started” is to a known memory location that never changes (even between IE and Firefox!), which is only possible because the Flash AX control always loads at the same address in memory every time. If Adobe would have opted-in to ASLR it would have made this technique MUCH less reliable.
On a random side note, here’s a fun tech tip for folks who happen to have a copy of LINK.EXE lying around (that is, if you have some version of Visual Studio installed). You can actually do what Adobe hasn’t done (yet) and make Flash opt-in to ASLR! Support for ASLR is usually added at link time using a linker switch (/DYNAMICBASE) but our linker can add this support to a binary at any time! To do this, just run the following commands from an elevated CMD prompt on Vista (assuming you have obtained a copy of link.exe from a Visual Studio install, or you can get it for free in the Visual C++ 2008 Express Edition available here: http://www.microsoft.com/express/vc/).
After ensuring you have the Visual Studio tools installed, close all running instances of Internet Explorer and launch the Visual Studio command prompt elevated and then run the following commands in the elevated command prompt:
For 32bit Vista installations with Flash9f (9.0.124.0):
icacls %windir%\System32\Macromed\Flash\Flash9f.ocx /save %temp%\Flash9f_acls.txt
icacls %windir%\System32\Macromed\Flash\Flash9f.ocx /remove everyone
attrib %windir%\System32\Macromed\Flash\Flash9f.ocx -r
link /edit /dynamicbase %windir%\System32\Macromed\Flash\Flash9f.ocx
attrib +r %windir%\System32\Macromed\Flash\Flash9f.ocx
icacls %windir%\System32\Macromed\Flash /restore %temp%\Flash9f_acls.txt
For 64bit Vista installations with Flash9f (9.0.124.0):
icacls %windir%\SysWOW64\Macromed\Flash\Flash9f.ocx /save %temp%\Flash9f_acls.txt
icacls %windir%\SysWOW64\Macromed\Flash\Flash9f.ocx /remove everyone
attrib %windir%\SysWOW64\Macromed\Flash\Flash9f.ocx -r
link /edit /dynamicbase %windir%\SysWOW64\Macromed\Flash\Flash9f.ocx
attrib +r %windir%\SysWOW64\Macromed\Flash\Flash9f.ocx
icacls %windir%\SysWOW64\Macromed\Flash /restore %temp%\Flash9f_acls.txt
(NOTE: Props to Adobe for the ”creative” use of ACLs and file attributes to prevent modifications to the binary! That seems like a nice defense in depth thing done to prevent patching the binary? J)
To verify that the Flash binary is now opting-in to ASLR you can use the dumpbin.exe command to view the headers like this from the Visual Studio command prompt:
For 32bit Vista installations with Flash9f (9.0.124.0):
Dumpbin.exe /headers %windir%\System32\Macromed\Flash\Flash9f.ocx
For 64bit Vista installations with Flash9f (9.0.124.0):
Dumpbin.exe /headers %windir%\SysWOW64\Macromed\Flash\Flash9f.ocx
And you can look for the following output:
Microsoft (R) COFF/PE Dumper Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file Flash9f.ocx
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86)
6 number of sections
47E8643E time date stamp Mon Mar 24 22:32:30 2008
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
210E characteristics
<snip>
OPTIONAL HEADER VALUES
10B magic # (PE32)
7.10 linker version
23F000 size of code
16F000 size of initialized data
<snip>
3AF000 size of image
1000 size of headers
2E261C checksum
2 subsystem (Windows GUI)
40 DLL characteristics
Dynamic base
In conclusion: the battle for the browser is a very important one as it is one of the primary conduits for stealing information from users, which is then sold, purchased, and traded in the underground economy. To date the bad guys have had it pretty easy with respect to reliable malicious code execution in browsers (via executable stacks and heaps), which has been aided by well-known heap spray techniques combined with the lack of hardware-enforced DEP and a lack of third parties opting-in to mitigation technologies like ASLR and DEP (until very recently). However, for several years now OEMs have been shipping PCs with CPUs that support hardware-enforced DEP and today, in current versions of IE 7 on XPSP2 and later operating systems, hardware enforced DEP can be enabled and tomorrow, it will even be on by default in IE 8 (on Vista SP1). In addition, while ASLR should be enabled by application developers when they compile and link their binaries, we’ve seen that it can be enabled at any time by modifying the DLL characteristics of the binary using freely available tools. We’ve also recently seen signs that some ISVs like Apple are starting to take these protection technologies seriously and are opting-in to them on the Windows platforms to help defend against attacks on their code and it is my belief that we will continue to see more third-party ISVs (like Adobe) opt-in to these technologies in the near future. Finally, while we’ve seen that the combination of DEP and ASLR can be used to defeat many of the current (and future) exploit techniques, we as defenders should not be complacent, as research is being done to find ways to bypass these technologies (possibly by leveraging applications which must perform Just in Time translation of bytecode in memory and then execute the resulting instructions such as Flash, Java, or .NET code running inside the browser as Mark Dowd has recently demonstrated). This is why, at the end of the day, we must all continue to improve our coding practices to produce the most secure code possible while ALSO ensuring that we are opting-in to all of the defenses offered by the operating systems on which our applications are running.
In the coming weeks I hope to publish a series of in-depth blog posts on the topic of our exploit prevention technologies such as /GS, DEP, and ASLR over in Microsoft’s Security Vulnerability Research & Defense blog.
-Rob