Abusing Silent Mitigations
Gorenc, Brian
Zuckerbraun, Simon
Hariri, Abdul-Aziz
In the summer of 2014, Microsoft silently introduced two new exploit mitigations into Internet Explorer with the goal of disrupting the threat landscape. These mitigations increase the complexity of successfully exploiting a use-after-free vulnerability. June's patch (MS14-035) introduced a separate heap, called Isolated Heap, which handles most of the DOM and supporting objects. July's patch (MS14-037) introduced a new strategy called MemoryProtection for freeing memory on the heap. This talk covers the evolution of the Isolated Heap and MemoryProtection mitigations, examines how they operate, and studies their weaknesses. It outlines techniques and steps an attacker must take to attack these mitigations to gain code execution on use-after-free vulnerabilities where possible. It describes how an attacker can use MemoryProtection as an oracle to determine the address at which a module will be loaded to bypass ASLR. Finally, additional recommended defenses are laid out to further harden Internet Explorer from these new attack vectors.
 Alright everybody, this is abusing silent mitigations, understanding internet explore, weaknesses in internet explorers, isolated heap and memory protection mitigations. We've got a lot to cover so we're just going to dive right in. So today we're going to go over a comprehensive set of research we did in mid-2014 related to the isolated heap and memory protection mitigations that were introduced to make UAF exploitation harder on internet explorer. It'll cover several attack techniques against isolated heap, some surgical tools to use against memory protection along with details over the ASLR bypass that was generated using memory protection. Then we'll follow it up with some, with the recommended defenses that we provided Microsoft. This research was awarded $125,000 from Microsoft's Bounty Program. It still is the highest payout from the Microsoft Bounty Program. It also included the first payout for the defenses side of the Bounty Program and we're going to go over all of those details today. So a quick overview, we all work for HP Zero Day Initiative Program. It's the world's largest vendor agnostic bug bounty program. We focus on purchasing vulnerabilities from researchers all over the world. We focus on getting those bugs fixed. We research advanced exploitation techniques. My name is Brian Gorance. I actually run the Zero Day Initiative Program. I spend most of my time doing root cause analysis on cases that come in doing internal vulnerability discovery. I also organize the PONDA own hacking competitions around the world. Because of those jobs, I get to work a lot with HP's legal organization, especially with the Wastner and stuff like that. Doing PONDA own is a lot more fun than it used to be. And the introduce Abdul. So I'm Abdul. I'm a security researcher working for ZDI. I've been working for HP Security Research for the past two years. And I do a lot of root cause analysis and bug discovery. Simon? Hi, I'm Simon Zuckerbrunn. On Twitter, I'm Hex Kitchen. I'm with ZDI. I've been with them for a little over a year. I do a lot of work with Internet Explorer. Yes. So it should be no surprise to anybody in this room that use after free vulnerabilities were a very popular choice for attackers who were targeting government websites and people who were visiting those sites and using them in watering hole attacks. But what you see here on the slide is a bunch of CDEs that were being used publicly or known about publicly. I mean, and really something had to be done. Every single month, it seemed that new attack was coming out that was leveraging a use after free and Internet Explorer. And finally, Microsoft did do something in mid-2014 to make attacking use after free vulnerabilities a little bit harder. And as a result, it seems that attackers have shifted away from use after free and Internet Explorer and are now focusing on flash vulnerabilities. So what exactly happened? Well, in MS-14035, they introduced isolated heap, which Abdul will go over. And the month following that, they introduced memory protection, which was a nice introduction to Internet Explorer to make use after free harder to exploit. The side effect that it had really was it made, i.e., fun to research again. We were receiving a lot of use after free vulnerabilities into the Zero Day Initiative program. And it was pretty much, you know, you hit the website and use after free happens, relatively easy to analyze, relatively easy to exploit. And this gave us, made it more fun to actually go and analyze those cases, made it a little more complicated. So this is the first time that we've ever actually like shown some of our submission trends into the program. And you can see we're kind of over 2012, 2013. You know, we've got, you know, in the teens kind of coming into the program every month, vulnerabilities into Internet Explorer. And we see a spike in early 2014. And this is because researchers all around the world were developing DOM fuzzers and basically sending their output to us for purchase. And so we kind of, for several months there, we're doing about 40 cases, high 30s every month analyzing, purchasing and submitting to Microsoft. And you see in mid 2014, the, a kind of a drop, and that's when isolated heap and memory protection came out. And we've kind of leveled off around 25 Zero Days in IE, coming through our program every month. So it keeps us busy. IE is one of our main, main vulnerability sources. Kind of talking about the research timeline a little bit before we dig into the attacks. You can kind of see all the key dates related to the research. I think some of the more important dates is we had the isolated heap of proof of concepts generated basically in under 10 days post the patch. Same with the surgical tools that we're going to use against memory protection. In the cases where it can be used, we're developed in under 10 days. We had our first working ASLR bypass for against memory protection or using memory protection in early September. We were awarded the $125,000 in November. And we kind of waited to disclose any of the details while we worked out payments to charities. We donated all of the money that we were, we won from the Bounty Program to three STEM organizations to encourage research and engineering. And we made the public announcement in February. The, in April, Microsoft came to us and said that they would not fix the issue, issues that we've discovered and would not be using any of the recommended offenses that we provided. So here we are sitting today at Recon, releasing all the details and all the proof of concepts that we've provided. So we'll talk about where to get all those at the end of the presentation. And so I'm going to hand it over to Abdul. He's going to go over all of the research related to isolated heap. So isolated heap was introduced in June 2014. So back then we noticed that there's a new heap created with a heap created API, Windows API. So basically the main purpose of isolated heap was allocating a lot of DOM objects, moving them to an isolated region, basically providing some kind of separation of DOM allocations against other type of allocations. This was really interesting from an exploitation point of view because it made things hard harder. As the classical ways of overriding freed objects like using strings and stuff like that would not apply anymore to a lot of DOM objects because they have been isolated, moved to a separate heap. And the classical string allocations are kept in the process heap. So basically just like any other mitigation, isolated heap is not perfect. Basically it does a good job by isolating certain allocations, but at the same time it allocates all the DOM objects in one heap. So basically an attacker can free one of these objects and then override it with whatever he wants, whatever type he wants. So basically this makes it clear that there's a type confusion issue here. That attacker can also override that object with another object of a different size so it doesn't have to be a specific of the same exact size so it can be smaller or bigger. So the attacks on isolated heap are very specific, like bug specific. Basically it's highly dependent on the offset being referenced at crash time. So most of the attacks that I'm going to be discussing in my next slides will be related to the type confusion issues and other misalignment issues. So the first attack I'll be discussing is the aligned allocation attack technique. Basically it's not just like you have a free isolated object, you free it and you allocate another isolated object at the same exact spot. But the only challenge here is that what type of object that you would actually allocate instead of that object. This scenario or this attack works well when you have a bug that or you just have to feel that actually the reference is a high offset. So basically you can always choose or find another object that you can control certain offsets like high offsets, certain values or have partial control of. To have this attack working properly we need to put a low fragmentation heap. The reason for that is that we're probably going to be allocating objects of different sizes so we don't want to end up having these allocations on different buckets so we want to have it on the same exact bucket. So the simplest way to achieve this is like in nutshell we have to trigger some freeing conditions like we have to free that specific object. Then in case we want to allocate like a bigger object we have to trigger like massage the heap in order to free multiple chunks, multiple free chunks. Later on we have to call us all the free chunks together in one big chunk. Then we have to space certain objects or replace that specific object with whatever object we want. We can do it with a bigger object, we can do it with a smaller object, it doesn't matter. It depends whatever scenario we have. And finally it's going to be like reusing or trigger their use. So this is my fancy graph here. It shows we have a C table row object and up front we have a C DOM text node. These are isolated basically in this specific example. The C table row, the fee happens on that specific object and then what we did is we overrode it with a C DOM text node. So the reason why we chose a C DOM text node is that in that specific case the bug was referencing I guess offset 30 and the C DOM text node contains an interesting value at offset 30 that we can partially control. So this is the Wendie bug dump, it's a before and after. Basically it shows the C table row before being freed and overwritten. And later on we overrode it with a C DOM text node. Highlighted in yellow is the offset that we're targeting. So basically C DOM text node contains a that specific offset 40000, which can be sprayed. So basically we partially control that offset. So this is a crash time. So when we have a successful overwrite and then we do reference everything, we're going to have a crash time, it's the referencing 40000 as you guys can see. So from there an attacker can spray that address and then control the flow of execution. So the second attack technique that I'll be discussing is the misaligned allocations attack technique. The aligned attack technique works well for high offsets, but in case we have a user after feed that references a low offset that can be kind of problematic. Because we don't have a lot of choices when it comes to DOM objects that we can overwrite it with and have specific low offsets that we can control or partially control. So basically the idea is if we have an object that's allocated at let's say address X, then we have to probably start allocations at X minus n. And then we're going to have one of the objects at X minus n being misaligned against the original object and then we're going to trigger a use and we're going to have an offset being referenced from the misaligned object. So the simple steps are basically influence the heap to call us a lot of free chunks together and then have them like in one big free chunk. Later on we have to spray random objects inside that big free chunk, but in a way that we're going to have one of the objects misaligned against the original object. And later on we're going to trigger the reuse and have it reference something from the misaligned object. So again this is my fancy graph here. Basically we have a C table row. At the front we have a C button, button object. Both are isolated. Then this bug targets the C table row object. Basically what we did is we freed a whole bunch of objects, coalesced all the free chunks together in one big chunk and then we started spraying random objects and then at a specific spot we had the C button misaligned against the original C button row. Basically then dereferencing an offset from the C button row. So basically if you bug dereferencing let's say offset X from C table row you're going to have it dereferencing something different. It's not the same offset from C button. So basically in a nutshell we need to stabilize the heap in a way to produce the same exact free chunk of the same size every time and then we're going to have to spray it with random objects. Basically in my specific example we were able to stabilize the heap with this specific code. It's not a generic code to always produce a free chunk of the same size, but it was like bug specific. It worked every time. In that specific example we had EDI pointing to the middle of the free chunk and later on we're going to see how it works. The free chunk is of size 110. It was always producing the same 110 free chunk. So as you guys can see this is a crash time. EBX comes from EDI. EDI points to the middle of a big free chunk of size 110. Later on we're going to see when we get control. So assuming that we were able to stabilize the heap in a way to give us the same free chunk of the same size every time then we would need to actually spray it with a bunch of objects. In this specific example I chose to target to have a misaligned C button object because at a certain offset it contains a value that I can spray. We can do it in a bunch of ways. We don't have to do it with a C button. Someone can argue that they can do it with a text area and then set some coordinates and you're going to have it working. But the idea here is just to have a misaligned object against the original object. This one worked well though. So this is a crash time. Actually we had EDI plus one C pointing to one two C zero zero four zero zero. It lands on that specific value which is an offset of the misaligned C button object. And as you guys can guess this value can be sprayed easily and then we can gain control. So in a nutshell just to wrap it up. Isolated heap does a good job isolating certain objects from other allocations. It's not perfect. Still have a lot of type confusion issues. It still have misalignment issues. Attacking isolated heap depends on several factors. It's more bug specific. We have to avoid low fragmentation heap as much as possible. And it depends on the offsets that being dereferenced. So I'm going to give it back to Brian to discuss memory protection. All right. So memory protection was introduced in July of 2014 and months after that. I think the patch the month after that they made some improvements to memory protection. What we noticed in the zero day initiative is we were analyzing cases and when that July patch came out we started to see that the cases that we hadn't purchased yet were turning into null pointer dereferences which was really interesting to us. And so we dig more into that and we found memory protection messing with the use after freeze that we were looking at. So we have to figure out what exactly is memory protection. Memory protection is a delayed frame mechanism inside of Internet Explorer and its purpose is to prevent blocks from being deallocated when they're referenced either on the stack or in processor registers. It keeps these blocks in a zeroed out state so that they're unusable and it adds it to a wait list. And every so often a reclamation process will occur. It will go through that wait list of objects and free them at the heap manager level. And so the way that they actually implemented this is instead of calling heap free on these objects they would call protected free on these objects instead. So we kind of need to understand how the heap, how the protected free function works. So the first thing that it does when protected free is called is it checks the wait list and checks to see if it's full. If the wait list is full it will go ahead and process the reclamation sweep, cleaning up the objects that are no longer referenced. After that it will add that block to the wait list and it will zero out and return to the user. If the wait list is not full, which is the case almost all of the time, it will check the aggregate size of the blocks on the wait list. If that aggregate size is over 100,000 bytes it will then perform a reclamation sweep, add the block to the wait list, zero it out and return to the caller. If for example the threshold has not been met it will add the block to the wait list without performing the reclamation sweep. It will zero out the block and return to the caller. So when we look at this the most important thing that we need to know about this function is we can ignore the first check as an attacker because we have control of what protected free actually the allocations that are going on. What we're going to focus on is the 100,000 byte threshold. What we're going to, the most important thing to know is that the reclamation sweep always occurs before the block is, a new block is added to the wait list and that's what we're going to leverage later on when we're trying to free at the heat manager level certain use after free conditions. What exactly is the reclamation process? Well there's that wait list which contains an entry for every block that has been requested to be deallocated and in that entry you've got the block base address, you have the block size and you have a flag that determines whether it's on the isolated heap or the process heap. It will iterate through those entries on the wait list and check the, check to see if there are any references to that object on the stack. It will check to see if there's any references to that object in the processor registers and if there is then the block is wait listed or continues to be wait listed. So after the reclamation sweep the block will still be there, still be zeroed out, still be allocated and can't be used by the attacker. If the references don't exist then we have the object will be freed at the heap manager level and released back. So in the cases where in a use after free where there is a reference on the stack or in the processor registers the memory protection is highly effective. It will keep those blocks allocated so that you can't allocate something underneath them and reuse them in a malicious way. So the, but there's that subset of use after freeze that aren't referenced anymore but there's still, memory protection is still changing the way that the application actually operates and so it causes them some challenges. So what are the challenges that memory protection presents an attacker for the subset of use after freeze that are no longer being referenced? Well first there's the deallocation delay and this is because there's that reclamation sweep that we're waiting for to perform before it would actually get deallocated. So there's several non-determinism that exists because of memory protection. First is the non-determinism produced by what we're calling stack junk which could be non-pointers or stale pointers that are left over in stack buffers that are not clear to their former use. It may just so happen that those stale pointers or values that are on the stack could point into an object that you want to be deallocated but because that stack junk exists the memory protection will not free that object. There's also complexity determining deallocation time due to the number of objects on the wait list so your timing could be off along with complex heap manager behavior due to reordering of the wait list which will result in unstable stack conditions which you kind of need for certain UAF situations. So what can we do? Well the first elementary attack technique is just the generic memory pressuring loop that's been used and used after freeze for a long time to force garbage collection where we'd allocate over 100,000 bytes worth of objects and then we would free them, force reclamation and clear it out. Well that definitely defeats the deallocation delay challenge but it doesn't stop the non-determinism challenge that exists due to memory protection. When we submitted this paper back in October of 2014 there was an unconditional reclamation step when WND PROC was entered to service a message on the threads main when WND PROC is actually entered. The this unconditional reclamation step post September 2014 was rendered non-functional by Microsoft and so this attack technique no longer works which was basically to delay execution of the exploit until that event happened and that unconditional reclamation supercured. Now used after freeze are sometimes timing based and so you need to, this doesn't always work but because Microsoft basically rendered it non-functional it really doesn't matter but for record it's there. So what do we want to do? We want to be able to remove the non-determination, we want to be able to delay deallocation and so what are we going to rely on? Well we're going to rely on the fact that memory protection first checks the size of the wait list and before it performs a reclamation sweep and only afterwards does it add that current block to the wait list. So when you call protected free on block at address A, A will definitely not be reclaimed on that call but it will definitely be on the wait list when the call is complete. So we're going to leverage that fact to make sure we can organize our calls in a way that will guarantee that we deallocate block, a block that we want to use and use after free. We're also going to rely on the fact that the isolated, that the, it doesn't matter which heap the object is on, it can be on the isolated heap or the processed heap. So step one, we want to be able to prep the wait list and we're going to do this by finding a method to trigger arbitrarily sized buffer allocations. So when we find that method, we'll allocate a buffer of 100,000 bytes. We will then free that buffer which because the wait, because the wait list, because of protected free and the way that it operates, it will add that block to the wait list and at this point we know the next time we call protected free, it will then free the blocks that are ready to be reclaimed. So you can kind of see that's the state of the wait list. At the point we have a set of blocks X on the wait list that are waiting to be freed. If they're not referenced anymore, then there's a block of 100,000 bytes that guarantees we hit the reclamation step on the next call of protected free. So we're going to trigger another block and the purpose of this, these steps is to get the wait list into a known state and an approximate size. So we're going to trigger the allocation of a block of size F. We're going to free that block which protected free will be called on that object and reclamation step will be performed because we've reached that threshold of 100,000 bytes. It will go through and iterate through that wait list freeing any block that's no longer referenced by the application on the stack or the process registers and it will also free block A which will bring the wait list into a consistent state and a good size. After all the freeing is done, it will add block B which will bring that wait list to a consistent size and at this point we have a good idea of what the wait list actually looks like. So next we're going to set up the freeing of block C which is the object that we want to perform our use after free attack on and our purpose now with these steps is to cleanly deallocate block C with the minimal amount of additional heap operations. So we call it, we free object C which calls protected free. We no longer are over the threshold so it adds the block to the wait list. Then we allocate that 100,000 byte block. We free that block but because we're not at the wait list, we're not at the threshold yet, it will add it to the wait list. We will then allocate another block which will put us over the wait list and trigger the reclamation step on the next call to protected free and at this point when we call free on object E, we will be freeing object C and object D and reliably. We know then exactly when we're able to deallocate block object C. We can then use the isolated heap techniques that Abdul talked about to perform our use after free attack against object C. You can see what the wait list looks at that point. But we need that method for arbitrarily allocating objects and arbitrarily freeing objects. We can't really rely on sysalloc string or sysfree string based string buffers because they don't use protected free and that's what we need. So in this case, Cster comes to our aid in MSHTML and we can use the DOM method, get elements by class name and in that method, it will create a Cster using the string value passed in and then later it will deallocate using protected free that string. And that's what we're going to use for the arbitrary allocation and deallocation of objects and manipulating the wait list and memory protection. To do this, you actually have to do a priming procedure against the DOM object and we'll talk about it in a second. And really the only limitations to this is the fact that there is a limitation on the size of the object. The smallest buffer you can use in Cster is 56 hex but there is no upper limit so we can be guaranteed that we're going to hit that threshold of 100,000 bytes in that check inside of protected free. So what does the code look like? Well, this is it. Pretty simple. First, we're going to create an object, a DOM object. We're going to call, the priming procedure is basically calling get elements by class name with the string that you're going to use later and keeping a reference to the returned value then any other subsequent call to get elements by class name using that string will reliably allocate a Cster at a size and deallocate that same object using protected free. And as a result, we can now take the steps that we laid out previously to reliably deallocate an object that is not completely mitigated by memory protection. We'll show you a video of one of the proof of concepts that we provided Microsoft of one of the cases that we had submitted, one of our researcher cases that we took to controlling a register. Basically it's using that get elements by class name technique to reliably deallocate that object and then using the isolated heap techniques, the aligned allocations that Abdul talked about to get control of the register, the EIP register. So now I'm going to hand it over to Simon and he will go over bypassing ASLR and also all the recommended defenses. Okay, in this section we're going to talk about how we were able to abuse memory protection to get a bypass of ASLR. So after I got comfortable with these techniques of making precision modifications to the memory protection state, I went back and I started thinking some more about something I'd read in a blog post by Fortinet back in July of 2014. And to progress from that blog post, back in 2013, Dion showed how conservative garbage collectors used by script engines can be attacked to leak information about heap addresses. So does memory protection provide a new surface for a similar attack? That's an interesting idea. In a sense, memory protection acts like a conservative garbage collector freeing allocated memory only if no references are found on the stack. This means that it might be susceptible to an attack similar to the garbage collection attack done by Dion. The key idea here is that when memory protection examines values on the stack, it doesn't understand anything about the semantics of those values. It treats each D word as if it is potentially a pointer. So if we'd like, we can plant a chosen value on the stack and memory protection will interpret it as a pointer. Memory protection will then exhibit different behavior depending on whether or not the integer that we chose corresponds to an address of white listed memory. Here we see a block of memory that is white listed. So let's say we plant an integer value on the stack and then trigger the memory protection reclamation routine. If the integer that we planted corresponds to an address anywhere within the block, then memory protection will respond in one way and by keeping the block on the wait list. But if the integer we planted is not within the wait listed block, then memory protection will behave in a different way and it will deallocate the block. So it's starting to sound like we may have a way to reveal information about the layout of the address space. We can repeatedly guess an address, plant it as an integer on the stack, and get memory protection to behave in a way that reveals whether or not we have correctly guessed the address of a certain targeted block in memory. In other words, we have an oracle. Or do we? Because at this point, there's still a very big problem. Let's take a look at the programmatic contract that's exposed by memory protection. Aside from that DLL notification, which is not something that gets called during normal program operation, memory protection does not ever return even a single piece of data from any of its methods. That's a problem. We can influence memory protection based on whether we've guessed the correct address or not, but to have an oracle, we need to have the ability to read some kind of response back. And memory protection's API gives us absolutely nothing. What this means is we need a side channel. So when I was thinking about this, the first thing that came to mind was that maybe we could use a timing attack. Then something else came along. It was in the summer of 2014, and some cases started coming into ZDI that were kind of unusual. We were seeing proof of concept code that would expose bad code paths in the Internet Explorer by subjecting the browser to memory pressure. The code would do some lengthy loop doing repeated DOM manipulations and also consuming memory. And at some point when address space was nearly exhausted and memory allocations were starting to fail, a code path would be triggered that was vulnerable. It was striking how a reasonably reliable trigger could be constructed in this way, even though the browser process was under such a high level of stress. I started to think about the idea of operating the browser in a regime of high memory pressure. It's relatively unexplored territory. What kinds of things can we make happen? It struck me as interesting. Something else I noticed was that when script requests an operation that requires a heap allocation and the allocation fails due to lack of available memory, the script receives an out of memory exception. Here we have a way for attackers script to detect whether an allocation was a success or a failure. All it needs to do is check for the exception. Here's the crucial insight. Script can detect whether an allocation succeeds or fails. Whether it succeeds or fails is a function of the existing state of the heap. In other words, JavaScript out of memory exceptions are a side channel that reveals information about the state of the heap. That's exactly the side channel we need in order to get information back from memory protection. Here's the high level view of how we consult the memory protection oracle. Don't be concerned about the exact details. I'm going to get to that just a bit later. For now, let's appreciate the high level structure of what we're going to do. Say we have a block of memory on the memory protection wait list. We want to consult the oracle to determine whether a certain address, X, is an address that falls within the block. We plant X on the stack as an integer and then we do something that triggers the reclamation routine. In response, memory protection modifies the heap in a way that's dependent on whether X points within the targeted block. How do we find out how memory protection has responded? We attempt a heap allocation that is designed to either succeed or fail depending on what memory protection has done to the heap. Then by checking for the presence or absence of an out of memory exception, we can make a deduction about how memory protection has behaved and then this reveals the answer to whether X falls within the targeted block of memory. Here's the whole chain of deductions we make. Presence or absence of an out of memory exception tells us something about the state of the heap. The state of the heap tells us something about how memory protection behaved and how memory protection behaved tells us whether X falls within the targeted block. That's the high level view. Clearly to actualize all this, it's going to take some pretty careful setup. Here's the thing. Going back to something I mentioned earlier, once you start thinking about what you can do in a regime of high memory pressure, some really interesting possibilities open up. Before going any further though, I'd like to refine what we mean by high memory pressure. It's more subtle than just piling on lots of pressure until there's almost no memory left. First of all, it's not really available memory we're talking about. It's availability of address space. In a 32-bit process, the limiting factor that's going to cause allocation failures is not memory exhaustion, it's address space exhaustion. The next thing to note, it's possible for allocations to fail even if there's plenty of address space left. It all just depends on how large of an allocation you're asking for. Also, it's not the aggregate amount of remaining address space that matters. It's whether a large enough contiguous free region can be found. Let's refine our idea as follows. Operating the browser in a regime of limited availability of large contiguous regions of free address space. Let's play with this a little bit. Suppose we spray the heap with one megabyte allocations until all address space is consumed. Then we free one of those one megabyte blocks. What's left is a one megabyte hole. That hole is going to be the one and only contiguous region of one megabytes of free addresses. Actually, you can leave lots of smaller holes also. But it doesn't change the fact that we have exactly one hole that's one megabyte big. Now we go back and we make one more one megabyte allocation. We know it will be placed right in that hole because that's the only place it can fit. We can actually keep doing this over and over, allocating a one megabyte block and freeing it, allocating a one megabyte block and freeing it. Every single time it's going to be allocated in exactly the same place. What happened if one time we tried to make that allocation but it failed? What would that tell us? What could make that happen? One thing that could make that happen is if some other allocation went up and came around and occupied that hole. But let's say we can rule that out because we know there are no other big allocations going on. What would that tell us? We might be able to conclude that what happened was that the last time that we freed the one megabyte allocation, it never really got freed because memory protection was holding on to it. We have a way of telling whether the hole is free or occupied by trying to make a new one megabyte allocation and checking to see if an out of memory exception is thrown. Now we have all the main pieces in place to make an attack possible. First we prepare memory so there's just one large contiguous free region, let's say one megabyte in size, but it could be any size we like. We're going to call that the hole or the region. What we're going to try to do is use memory protection as an oracle to determine where that hole is in memory. So we're going to guess an address X and we want to consult the oracle to determine if X falls within the hole. What we're going to do is first we'll make a one megabyte allocation so now the hole is occupied. Next we're going to free that allocation, meaning that it gets passed to protected free and protected free puts the allocation on the wait list. As far as the windows heat manager is concerned the memory is still allocated. Then we're going to plant X as an integer on the stack and while X is there on the stack we're going to do something that triggers memory reclamation. Now what happens next depends on whether X falls within this one megabyte address region or not. If X falls within the address region then when memory protection performs reclamation it will keep this allocation on the wait list and it won't free it on the heat manager level. Otherwise if X doesn't fall within the region then memory protection will remove this allocation from the wait list and invoke heat free which completely deallocates that block. So this shows the two possible states that we can end up in. If X falls within the region then the hole stays occupied but if X does not fall within the region then the hole gets opened up again. Last step to tell which of these two states we just ended up in all we need to do is make one more one megabyte allocation. If it succeeds we know that the hole got opened and this means that X wasn't within the region but if we get an out of memory extension then we know that the hole stayed occupied which tells us that X falls within the region. Now we have an answer from the oracle and then by repeating this process with different values of X we can use the oracle to find out exactly where this one megabyte hole is in memory. Now I'm going to go back to this idea just one more time when we operate the browser in a regime of limited availability of contiguous regions of free address space the new possibilities that arise can be quite interesting and actually is going to lead us to what we can do next. So far what we have is a way to prepare the address space so there's just one large hole of available addresses of a size of our choosing and then to use the memory protection oracle to determine the exact addresses of that hole. How can we make good use of this ability? What can an attacker gain from knowing the address of a hole in the address space? We can load a module into it. We can start by creating a hole that's exactly the right size for loading a particular module then using the memory protection oracle we leak the address of the hole finally we cause the loading of the module. It gets loaded exactly at the beginning of the hole because that's the only place where it's going to fit. So it's actually an SLR bypass and it runs really efficiently and reliably we're going to show a demo video here what it looks like to run. This is a fully patched IE. On that demo video it's got the address already popping up. And there it is. Okay, so this has been a lot of fun. It started out looking like something that was non-exploitable turned out in the end to be a reliable SLR bypass. The key insight that made it possible is that JavaScript out of memory exceptions are a side channel that reveals critical information about the state of the heap. I don't think it's been recognized before. There are really interesting possibilities that open up when you operate the browser under memory pressure. Okay, so we've made several recommendations to Microsoft for ways that it can improve isolated heap and memory protection to harden them against the attacks we've discovered. In regard to memory protection we've seen how in various situations the attacker can benefit from the ability to make precision modifications to the state of memory protection. And we've even shown that this leads to a breakdown of ASLR. To make memory protection resistant to attempt to normalize and to control its state we make the recommendation to remove memory protection from array and buffer allocations. This means that memory protection would apply only to scalar allocations. Our rationale is that one almost never finds an exploitable use after free condition in Internet Explorer where the freed object is an array or a buffer. On very rare occasion we have seen UAF cases submitted to a zero-day initiative where the freed object is some sort of string data. But in every case these have turned out to be non-exploitable conditions. And since UAFs of arrays and buffers in Internet Explorer are rare to non-existent, the benefit of applying memory protection to these allocations is doubtful. On the other hand we've demonstrated how it can be a very significant benefit to an attacker with air-fulfill that memory protection will be a stronger defense if applied to scalar allocations only. Our next suggestion pertains to strengthening ASLR. Taking a look at how we got ASLR to fail, what you can notice is that the attacker was able to violate one of ASLR's assumptions by preparing the address space in a particular way. Do you know Diozovi made a similar observation when he said, thinking about security mitigations like DEP and ASLR designed for service-ide code doesn't work when you give your attacker an interpreter. So I feel that ASLR needs to be strengthened for the browser because the browser is an inherently more hostile environment. Here's the particular assumption that ASLR makes that when it chooses a load address for a module from among the set of possible load addresses that this random choice will exhibit a significant amount of entropy. But an attacker can break this assumption by radically narrowing the set of possible load addresses before the module loads. Our recommendation is to enhance ASLR by adding an additional check before loading a module. This check is to ensure that there really do exist a multiplicity of addresses at which the requested module could load before actually performing the random selection of a load address. If the number of possible load addresses is below a certain threshold, the module load should fail. Since loading the module under this circumstance could significantly weaken the security of the entire process. Ideally this mitigation would be implemented at the kernel level and it could be made available on an opt-in basis for executables such as browsers which are a more hostile environment as we mentioned. It would also be possible to implement this mitigation in user-land code at the application level by hooking the relevant system calls. Here's a quick-site sequence diagram showing how the entropy check works. The application requests the module to be loaded. Kernel examines how many places of memory available for the module to load. Kernel decides that the minimum threshold is met and it proceeds to choose one of the possible load addresses at random, loads the module, and it returns success to the caller. While the kernel is responding to the module load request, it locks changes to the address space to prevent a time of check, time of use attack. Another time the application requests the module to be loaded. Kernel examines how many places of memory available for the module to load. This time the kernel detects that there are too few possible load addresses. The kernel denies the module load request, returns failure to the application, and it shows the locking that takes place during the second request. Next recommendation is regard to out-of-memory exceptions. We've shown that JavaScript out-of-memory exceptions are a side channel that reveals information about the state of the heap. Although this leaked bit of information might seem insignificant at first, we have a very good idea of how it can be leveraged to great effect. It should also be mentioned that out-of-memory exceptions greatly aid the attacker in setting up conditions of memory pressure that are needed for our ASLR bypass attack, as well as triggering other vulnerabilities that are dependent on memory pressure. We therefore recommend considering eliminating out-of-memory exceptions in script. When an allocation fails due to memory or address space exhaustion, instead of passing an exception up to script code where it can be handled, the condition should be considered as fatal to the process, or at least fatal to script execution within the process. This seems unlikely to have a significant negative impact upon legitimate web pages and web applications. Finally, we recommend taking ISO heap to the next logical step by creating additional separate heaps. Ideally one could have a separate heap for each scalar type. This would bring two great benefits. First, a use-after-free condition could never lead to type confusion, since every type is confined to its own heap. Secondly, since each heap consists entirely of objects of homogenous size, misalignments will not arise. Actually, this last point is made trickier by storage of C++ arrays, because C++ arrays can introduce misalignment, because when an array is stored, the individual elements don't have heap metadata added to them, the way that heap metadata is added to the individual scalar allocations, and plus the C++ compiler adds some metadata of its own to store the arrays' dimensions. It's actually possible to use C++ arrays to introduce misalignment into heaps. However, as we've mentioned, exploitable UAFs in arrays and buffers are extremely rare in Internet Explorer, so we recommend just leaving all array and buffer allocations on the default heap instead. If we do that, it should become impossible for an attacker to produce misalignments on the isolated heaps. Actually, there's another completely separate reason why it's best to leave arrays and buffers on the main process heap. I'd like to digress a moment to explain why. There's something that doesn't get much attention when iso-heap is discussed, and that's what we could be called an address-reuse attack. What's that? Well, consider how iso-heap is supposed to ensure that when a DOM object is freed, then an attacker won't be able to allocate some other non-dom type object in its place, such as a string. Iso-heap tries to ensure this by making sure that DOM allocations and string allocations don't happen on the same heap. But here's the thing. The attacker doesn't care about heaps. The attacker only cares about addresses. Is it possible for the address of a freed DOM object to later on be the address of a string allocation? Well, this would become possible if, say, the iso-heap, which is the heap on which DOM objects are stored, sometimes relinquishes control of virtual address space that it no longer needs. That would create the opportunity for those same addresses to later become part of a different heap, such as a process heap. And a string could be allocated there. Is this attack actually possible? Currently, this attack is not possible. Here's why. The way the Windows heap manager works with small allocations is that it puts them inside regions of virtual memory called heap segments. And once a particular heap reserves a segment, it never relinquishes control of those virtual addresses. For as long as that heap lives, it's never going to allow those addresses to become part of any other heap. And today, the iso-heap is used only for small-scalar allocations, so it's good. But if instead, i.e., tried to protect large buffer allocations by placing them on the iso-heap, then isolation wouldn't be guaranteed. For large allocations, the heap manager doesn't use heap segments. When the heap manager freed the buffer, it would relinquish control over the virtual addresses involved, and later on, those virtual addresses could become part of a different heap, breaking the isolation. So what this means for us is that it's pointless using Windows heap manager to try to protect buffers and arrays by placing them on an isolated heap. That isolation could be easily broken using an address reuse attack. The bottom line is, best way is to keep array and buffer allocations on the default heap and have a separate isolated heap for every type of scalar allocation. Then those isolated heaps will be completely immune to type confusion and misalignment issues. So having a separate heap for every scalar type is highly beneficial, but the drawback is that it may be too wasteful of address space in a 32-bit process where address space is a scarce resource. We're faced with a trade-off between security and address space usage. What can we do to make the best of this trade-off? We're only going to be able to create a limited number of heaps. How can we make things as hard as possible for an attacker using only a limited number of heaps? In whatever way we make assignments of types to heaps, an attacker who has discovered a UAF on one particular heap will try to construct an exploit via type confusion and or misalignment by making use of the various types that we have assigned to that same heap. Unless we randomize the assignments between heaps and types, we can break the monoculture of heap partitioning and instead random partitioning at process startup time. Denies to the attacker the ability to write a reliable exploit that relies on knowledge of which types are co-located on a heap. It optimizes the defender's advantage when we make the trade-off between security and the number of heaps we're willing to create. Here's how randomized heap partitioning can function. At process startup time, the process creates a certain configured number of heaps. This number should be chosen based on the trade-off between security and address space usage. Then, it allocates an array having one element corresponding to each scalar type in the application. The initialization code then populates each element of the array with a heap handle chosen at random from among the available heaps. Then, whenever application code performs a heap allocation of a particular scalar type, just looks up the appropriate heap handle in the array and uses that heap and the same applies to the allocation. We expect that randomized heap partitioning will make exploits a lot messier because the types that are needed for type confusion and or misalignment are never guaranteed to be on the heap that the attacker needs them to be on. Exploit reliability will suffer as a result. Failed exploit attempts typically result in process crashes, making attacks easier to detect. This means that ODays in the wild can be discovered and patched more quickly. Also the attacker gains no knowledge from crashes since a new randomization is done with every process startup. In some randomized heap partitioning, CIM serves to minimize the benefit that the attacker can hope to attain relative to the cost of discovering UAFs and developing and fielding exploits for them. To recap the new defenses we are recommending, remove memory protection from arrays and buffers. Strengthen ASLR by making a positive check for entropy in load address selection. After eliminating JavaScript out of memory exceptions, create one heap type in 64-bit processes. Use randomized heap partitioning in 32-bit processes. All right. So just kind of a little bit of conclusion. Of course we have many use after freeze coming into our program. We have attacks against isolated heap. We have attacks against memory protection and an ASLR break. So why not put it all together into an exploit? So we did that for the bounty submission. So not that most of us have not seen a IEA exploit before, but at the time it was the latest patched IEA. And what you're going to see it do is it's going to run and break ASLR. It will say retry once and then it will get the load address and then exploit the use after free vulnerability and pop calc. So we can chain this with one of the many sandbox escapes that we know about in IEA to do some damage. So we are releasing all of the research that we did for the Microsoft bounty program. It's actually up on GitHub right now. I just checked. We've released the white paper that we submitted to Microsoft. We have proof of concepts up there for the memory protection and isolated heap stuff. We have put ASLR bypasses up that targets Windows 7, IEA 11 in default configuration. We've also uploaded a ASLR bypass that works against Windows 8.1, IEA 11 in default configuration up there because they decided not to fix it even though we provided quite a bit of recommended defenses. So in conclusion, this research was a lot of fun. We got to kind of come at it from another side. We're usually the ones deciding how much to pay for vulnerabilities and exploits. And in this case, we put our research up to another company to judge it. And so it was an interesting experience. We learned a lot going through it. I really had a good experience with Microsoft dealing with them. So this is where we sit today. Are there any questions? Yes? Hello. Do you have any technique for avoiding LFH after users in some indeterminate state of browsing? This can be a little bit tricky. I don't think there's a generic way to do it, but it's solely bug-specific. Hey, some of those slides read patent pending. Are these mitigations encumbered by patents? Some of them are patent pending. For Microsoft, specifically with the way that the bounty program works, the release's rights to them to use them all. Thanks. My memory protection technique does not apply to 64-bit processes. Any other? All right. Thank you for your time. Enjoy playing with the proof of concepts. Thank you.
 Alright everybody, this is abusing silent mitigations, understanding internet explore,  weaknesses in internet explorers, isolated heap and memory protection mitigations.  We've got a lot to cover so we're just going to dive right in.  So today we're going to go over a comprehensive set of research we did in mid-2014 related  to the isolated heap and memory protection mitigations that were introduced to make UAF  exploitation harder on internet explorer.  It'll cover several attack techniques against isolated heap, some surgical tools to use  against memory protection along with details over the ASLR bypass that was generated using  memory protection.  Then we'll follow it up with some, with the recommended defenses that we provided Microsoft.  This research was awarded $125,000 from Microsoft's Bounty Program.  It still is the highest payout from the Microsoft Bounty Program.  It also included the first payout for the defenses side of the Bounty Program and we're  going to go over all of those details today.  So a quick overview, we all work for HP Zero Day Initiative Program.  It's the world's largest vendor agnostic bug bounty program.  We focus on purchasing vulnerabilities from researchers all over the world.  We focus on getting those bugs fixed.  We research advanced exploitation techniques.  My name is Brian Gorance.  I actually run the Zero Day Initiative Program.  I spend most of my time doing root cause analysis on cases that come in doing internal  vulnerability discovery.  I also organize the PONDA own hacking competitions around the world.  Because of those jobs, I get to work a lot with HP's legal organization, especially with  the Wastner and stuff like that.  Doing PONDA own is a lot more fun than it used to be.  And the introduce Abdul.  So I'm Abdul.  I'm a security researcher working for ZDI.  I've been working for HP Security Research for the past two years.  And I do a lot of root cause analysis and bug discovery.  Simon?  Hi, I'm Simon Zuckerbrunn.  On Twitter, I'm Hex Kitchen.  I'm with ZDI.  I've been with them for a little over a year.  I do a lot of work with Internet Explorer.  Yes.  So it should be no surprise to anybody in this room that use after free vulnerabilities were  a very popular choice for attackers who were targeting government websites and people who  were visiting those sites and using them in watering hole attacks.  But what you see here on the slide is a bunch of CDEs that were being used publicly or known  about publicly.  I mean, and really something had to be done.  Every single month, it seemed that new attack was coming out that was leveraging a use after  free and Internet Explorer.  And finally, Microsoft did do something in mid-2014 to make attacking use after free  vulnerabilities a little bit harder.  And as a result, it seems that attackers have shifted away from use after free and Internet  Explorer and are now focusing on flash vulnerabilities.  So what exactly happened?  Well, in MS-14035, they introduced isolated heap, which Abdul will go over.  And the month following that, they introduced memory protection, which was a nice introduction  to Internet Explorer to make use after free harder to exploit.  The side effect that it had really was it made, i.e., fun to research again.  We were receiving a lot of use after free vulnerabilities into the Zero Day Initiative  program.  And it was pretty much, you know, you hit the website and use after free happens, relatively  easy to analyze, relatively easy to exploit.  And this gave us, made it more fun to actually go and analyze those cases, made it a little  more complicated.  So this is the first time that we've ever actually like shown some of our submission  trends into the program.  And you can see we're kind of over 2012, 2013.  You know, we've got, you know, in the teens kind of coming into the program every month,  vulnerabilities into Internet Explorer.  And we see a spike in early 2014.  And this is because researchers all around the world were developing DOM fuzzers and  basically sending their output to us for purchase.  And so we kind of, for several months there, we're doing about 40 cases, high 30s every  month analyzing, purchasing and submitting to Microsoft.  And you see in mid 2014, the, a kind of a drop, and that's when isolated heap and memory  protection came out.  And we've kind of leveled off around 25 Zero Days in IE, coming through our program every  month.  So it keeps us busy.  IE is one of our main, main vulnerability sources.  Kind of talking about the research timeline a little bit before we dig into the attacks.  You can kind of see all the key dates related to the research.  I think some of the more important dates is we had the isolated heap of proof of concepts  generated basically in under 10 days post the patch.  Same with the surgical tools that we're going to use against memory protection.  In the cases where it can be used, we're developed in under 10 days.  We had our first working ASLR bypass for against memory protection or using memory protection  in early September.  We were awarded the $125,000 in November.  And we kind of waited to disclose any of the details while we worked out payments to charities.  We donated all of the money that we were, we won from the Bounty Program to three STEM  organizations to encourage research and engineering.  And we made the public announcement in February.  The, in April, Microsoft came to us and said that they would not fix the issue, issues  that we've discovered and would not be using any of the recommended offenses that we provided.  So here we are sitting today at Recon, releasing all the details and all the proof of concepts  that we've provided.  So we'll talk about where to get all those at the end of the presentation.  And so I'm going to hand it over to Abdul.  He's going to go over all of the research related to isolated heap.  So isolated heap was introduced in June 2014.  So back then we noticed that there's a new heap created with a heap created API, Windows  API.  So basically the main purpose of isolated heap was allocating a lot of DOM objects, moving  them to an isolated region, basically providing some kind of separation of DOM allocations  against other type of allocations.  This was really interesting from an exploitation point of view because it made things hard  harder.  As the classical ways of overriding freed objects like using strings and stuff like  that would not apply anymore to a lot of DOM objects because they have been isolated,  moved to a separate heap.  And the classical string allocations are kept in the process heap.  So basically just like any other mitigation, isolated heap is not perfect.  Basically it does a good job by isolating certain allocations, but at the same time  it allocates all the DOM objects in one heap.  So basically an attacker can free one of these objects and then override it with whatever  he wants, whatever type he wants.  So basically this makes it clear that there's a type confusion issue here.  That attacker can also override that object with another object of a different size so  it doesn't have to be a specific of the same exact size so it can be smaller or bigger.  So the attacks on isolated heap are very specific, like bug specific.  Basically it's highly dependent on the offset being referenced at crash time.  So most of the attacks that I'm going to be discussing in my next slides will be related  to the type confusion issues and other misalignment issues.  So the first attack I'll be discussing is the aligned allocation attack technique.  Basically it's not just like you have a free isolated object, you free it and you allocate  another isolated object at the same exact spot.  But the only challenge here is that what type of object that you would actually allocate  instead of that object.  This scenario or this attack works well when you have a bug that or you just have to feel  that actually the reference is a high offset.  So basically you can always choose or find another object that you can control certain  offsets like high offsets, certain values or have partial control of.  To have this attack working properly we need to put a low fragmentation heap.  The reason for that is that we're probably going to be allocating objects of different  sizes so we don't want to end up having these allocations on different buckets so we want  to have it on the same exact bucket.  So the simplest way to achieve this is like in nutshell we have to trigger some freeing  conditions like we have to free that specific object.  Then in case we want to allocate like a bigger object we have to trigger like massage the  heap in order to free multiple chunks, multiple free chunks.  Later on we have to call us all the free chunks together in one big chunk.  Then we have to space certain objects or replace that specific object with whatever object  we want.  We can do it with a bigger object, we can do it with a smaller object, it doesn't matter.  It depends whatever scenario we have.  And finally it's going to be like reusing or trigger their use.  So this is my fancy graph here.  It shows we have a C table row object and up front we have a C DOM text node.  These are isolated basically in this specific example.  The C table row, the fee happens on that specific object and then what we did is we  overrode it with a C DOM text node.  So the reason why we chose a C DOM text node is that in that specific case the bug was  referencing I guess offset 30 and the C DOM text node contains an interesting value at  offset 30 that we can partially control.  So this is the Wendie bug dump, it's a before and after.  Basically it shows the C table row before being freed and overwritten.  And later on we overrode it with a C DOM text node.  Highlighted in yellow is the offset that we're targeting.  So basically C DOM text node contains a that specific offset 40000, which can be sprayed.  So basically we partially control that offset.  So this is a crash time.  So when we have a successful overwrite and then we do reference everything, we're going  to have a crash time, it's the referencing 40000 as you guys can see.  So from there an attacker can spray that address and then control the flow of execution.  So the second attack technique that I'll be discussing is the misaligned allocations  attack technique.  The aligned attack technique works well for high offsets, but in case we have a user after  feed that references a low offset that can be kind of problematic.  Because we don't have a lot of choices when it comes to DOM objects that we can overwrite  it with and have specific low offsets that we can control or partially control.  So basically the idea is if we have an object that's allocated at let's say address X, then  we have to probably start allocations at X minus n.  And then we're going to have one of the objects at X minus n being misaligned against the  original object and then we're going to trigger a use and we're going to have an offset being  referenced from the misaligned object.  So the simple steps are basically influence the heap to call us a lot of free chunks together  and then have them like in one big free chunk.  Later on we have to spray random objects inside that big free chunk, but in a way that we're  going to have one of the objects misaligned against the original object.  And later on we're going to trigger the reuse and have it reference something from the misaligned  object.  So again this is my fancy graph here.  Basically we have a C table row.  At the front we have a C button, button object.  Both are isolated.  Then this bug targets the C table row object.  Basically what we did is we freed a whole bunch of objects, coalesced all the free chunks  together in one big chunk and then we started spraying random objects and then at a specific  spot we had the C button misaligned against the original C button row.  Basically then dereferencing an offset from the C button row.  So basically if you bug dereferencing let's say offset X from C table row you're going  to have it dereferencing something different.  It's not the same offset from C button.  So basically in a nutshell we need to stabilize the heap in a way to produce the same exact  free chunk of the same size every time and then we're going to have to spray it with  random objects.  Basically in my specific example we were able to stabilize the heap with this specific  code.  It's not a generic code to always produce a free chunk of the same size, but it was  like bug specific.  It worked every time.  In that specific example we had EDI pointing to the middle of the free chunk and later  on we're going to see how it works.  The free chunk is of size 110.  It was always producing the same 110 free chunk.  So as you guys can see this is a crash time.  EBX comes from EDI.  EDI points to the middle of a big free chunk of size 110.  Later on we're going to see when we get control.  So assuming that we were able to stabilize the heap in a way to give us the same free  chunk of the same size every time then we would need to actually spray it with a bunch  of objects.  In this specific example I chose to target to have a misaligned C button object because  at a certain offset it contains a value that I can spray.  We can do it in a bunch of ways.  We don't have to do it with a C button.  Someone can argue that they can do it with a text area and then set some coordinates  and you're going to have it working.  But the idea here is just to have a misaligned object against the original object.  This one worked well though.  So this is a crash time.  Actually we had EDI plus one C pointing to one two C zero zero four zero zero.  It lands on that specific value which is an offset of the misaligned C button object.  And as you guys can guess this value can be sprayed easily and then we can gain control.  So in a nutshell just to wrap it up.  Isolated heap does a good job isolating certain objects from other allocations.  It's not perfect.  Still have a lot of type confusion issues.  It still have misalignment issues.  Attacking isolated heap depends on several factors.  It's more bug specific.  We have to avoid low fragmentation heap as much as possible.  And it depends on the offsets that being dereferenced.  So I'm going to give it back to Brian to discuss memory protection.  All right.  So memory protection was introduced in July of 2014 and months after that.  I think the patch the month after that they made some improvements to memory protection.  What we noticed in the zero day initiative is we were analyzing cases and when that July  patch came out we started to see that the cases that we hadn't purchased yet were turning  into null pointer dereferences which was really interesting to us.  And so we dig more into that and we found memory protection messing with the use after  freeze that we were looking at.  So we have to figure out what exactly is memory protection.  Memory protection is a delayed frame mechanism inside of Internet Explorer and its purpose  is to prevent blocks from being deallocated when they're referenced either on the stack  or in processor registers.  It keeps these blocks in a zeroed out state so that they're unusable and it adds it to  a wait list.  And every so often a reclamation process will occur.  It will go through that wait list of objects and free them at the heap manager level.  And so the way that they actually implemented this is instead of calling heap free on these  objects they would call protected free on these objects instead.  So we kind of need to understand how the heap, how the protected free function works.  So the first thing that it does when protected free is called is it checks the wait list  and checks to see if it's full.  If the wait list is full it will go ahead and process the reclamation sweep, cleaning  up the objects that are no longer referenced.  After that it will add that block to the wait list and it will zero out and return to the  user.  If the wait list is not full, which is the case almost all of the time, it will check  the aggregate size of the blocks on the wait list.  If that aggregate size is over 100,000 bytes it will then perform a reclamation sweep, add  the block to the wait list, zero it out and return to the caller.  If for example the threshold has not been met it will add the block to the wait list  without performing the reclamation sweep.  It will zero out the block and return to the caller.  So when we look at this the most important thing that we need to know about this function  is we can ignore the first check as an attacker because we have control of what protected  free actually the allocations that are going on.  What we're going to focus on is the 100,000 byte threshold.  What we're going to, the most important thing to know is that the reclamation sweep always  occurs before the block is, a new block is added to the wait list and that's what we're  going to leverage later on when we're trying to free at the heat manager level certain  use after free conditions.  What exactly is the reclamation process?  Well there's that wait list which contains an entry for every block that has been requested  to be deallocated and in that entry you've got the block base address, you have the block  size and you have a flag that determines whether it's on the isolated heap or the process heap.  It will iterate through those entries on the wait list and check the, check to see if there  are any references to that object on the stack.  It will check to see if there's any references to that object in the processor registers  and if there is then the block is wait listed or continues to be wait listed.  So after the reclamation sweep the block will still be there, still be zeroed out, still  be allocated and can't be used by the attacker.  If the references don't exist then we have the object will be freed at the heap manager  level and released back.  So in the cases where in a use after free where there is a reference on the stack or  in the processor registers the memory protection is highly effective.  It will keep those blocks allocated so that you can't allocate something underneath them  and reuse them in a malicious way.  So the, but there's that subset of use after freeze that aren't referenced anymore but  there's still, memory protection is still changing the way that the application actually  operates and so it causes them some challenges.  So what are the challenges that memory protection presents an attacker for the subset of use  after freeze that are no longer being referenced?  Well first there's the deallocation delay and this is because there's that reclamation  sweep that we're waiting for to perform before it would actually get deallocated.  So there's several non-determinism that exists because of memory protection.  First is the non-determinism produced by what we're calling stack junk which could be non-pointers  or stale pointers that are left over in stack buffers that are not clear to their former  use.  It may just so happen that those stale pointers or values that are on the stack could point  into an object that you want to be deallocated but because that stack junk exists the memory  protection will not free that object.  There's also complexity determining deallocation time due to the number of objects on the wait  list so your timing could be off along with complex heap manager behavior due to reordering  of the wait list which will result in unstable stack conditions which you kind of need for  certain UAF situations.  So what can we do?  Well the first elementary attack technique is just the generic memory pressuring loop  that's been used and used after freeze for a long time to force garbage collection where  we'd allocate over 100,000 bytes worth of objects and then we would free them, force  reclamation and clear it out.  Well that definitely defeats the deallocation delay challenge but it doesn't stop the non-determinism  challenge that exists due to memory protection.  When we submitted this paper back in October of 2014 there was an unconditional reclamation  step when WND PROC was entered to service a message on the threads main when WND PROC  is actually entered.  The this unconditional reclamation step post September 2014 was rendered non-functional  by Microsoft and so this attack technique no longer works which was basically to delay  execution of the exploit until that event happened and that unconditional reclamation  supercured.  Now used after freeze are sometimes timing based and so you need to, this doesn't always  work but because Microsoft basically rendered it non-functional it really doesn't matter  but for record it's there.  So what do we want to do?  We want to be able to remove the non-determination, we want to be able to delay deallocation and  so what are we going to rely on?  Well we're going to rely on the fact that memory protection first checks the size of  the wait list and before it performs a reclamation sweep and only afterwards does it add that  current block to the wait list.  So when you call protected free on block at address A, A will definitely not be reclaimed  on that call but it will definitely be on the wait list when the call is complete.  So we're going to leverage that fact to make sure we can organize our calls in a way that  will guarantee that we deallocate block, a block that we want to use and use after free.  We're also going to rely on the fact that the isolated, that the, it doesn't matter  which heap the object is on, it can be on the isolated heap or the processed heap.  So step one, we want to be able to prep the wait list and we're going to do this by finding  a method to trigger arbitrarily sized buffer allocations.  So when we find that method, we'll allocate a buffer of 100,000 bytes.  We will then free that buffer which because the wait, because the wait list, because of  protected free and the way that it operates, it will add that block to the wait list and  at this point we know the next time we call protected free, it will then free the blocks  that are ready to be reclaimed.  So you can kind of see that's the state of the wait list.  At the point we have a set of blocks X on the wait list that are waiting to be freed.  If they're not referenced anymore, then there's a block of 100,000 bytes that guarantees we  hit the reclamation step on the next call of protected free.  So we're going to trigger another block and the purpose of this, these steps is to get  the wait list into a known state and an approximate size.  So we're going to trigger the allocation of a block of size F. We're going to free that  block which protected free will be called on that object and reclamation step will be  performed because we've reached that threshold of 100,000 bytes.  It will go through and iterate through that wait list freeing any block that's no longer  referenced by the application on the stack or the process registers and it will also  free block A which will bring the wait list into a consistent state and a good size.  After all the freeing is done, it will add block B which will bring that wait list to  a consistent size and at this point we have a good idea of what the wait list actually  looks like.  So next we're going to set up the freeing of block C which is the object that we want  to perform our use after free attack on and our purpose now with these steps is to cleanly  deallocate block C with the minimal amount of additional heap operations.  So we call it, we free object C which calls protected free.  We no longer are over the threshold so it adds the block to the wait list.  Then we allocate that 100,000 byte block.  We free that block but because we're not at the wait list, we're not at the threshold  yet, it will add it to the wait list.  We will then allocate another block which will put us over the wait list and trigger  the reclamation step on the next call to protected free and at this point when we call free on  object E, we will be freeing object C and object D and reliably.  We know then exactly when we're able to deallocate block object C.  We can then use the isolated heap techniques that Abdul talked about to perform our use  after free attack against object C.  You can see what the wait list looks at that point.  But we need that method for arbitrarily allocating objects and arbitrarily freeing objects.  We can't really rely on sysalloc string or sysfree string based string buffers because  they don't use protected free and that's what we need.  So in this case, Cster comes to our aid in MSHTML and we can use the DOM method, get  elements by class name and in that method, it will create a Cster using the string value  passed in and then later it will deallocate using protected free that string.  And that's what we're going to use for the arbitrary allocation and deallocation of  objects and manipulating the wait list and memory protection.  To do this, you actually have to do a priming procedure against the DOM object and we'll  talk about it in a second.  And really the only limitations to this is the fact that there is a limitation on the  size of the object.  The smallest buffer you can use in Cster is 56 hex but there is no upper limit so we can  be guaranteed that we're going to hit that threshold of 100,000 bytes in that check inside  of protected free.  So what does the code look like?  Well, this is it.  Pretty simple.  First, we're going to create an object, a DOM object.  We're going to call, the priming procedure is basically calling get elements by class  name with the string that you're going to use later and keeping a reference to the returned  value then any other subsequent call to get elements by class name using that string will  reliably allocate a Cster at a size and deallocate that same object using protected free.  And as a result, we can now take the steps that we laid out previously to reliably deallocate  an object that is not completely mitigated by memory protection.  We'll show you a video of one of the proof of concepts that we provided Microsoft of  one of the cases that we had submitted, one of our researcher cases that we took to controlling  a register.  Basically it's using that get elements by class name technique to reliably deallocate  that object and then using the isolated heap techniques, the aligned allocations that Abdul  talked about to get control of the register, the EIP register.  So now I'm going to hand it over to Simon and he will go over bypassing ASLR and also  all the recommended defenses.  Okay, in this section we're going to talk about how we were able to abuse memory protection  to get a bypass of ASLR.  So after I got comfortable with these techniques of making precision modifications to the memory  protection state, I went back and I started thinking some more about something I'd read  in a blog post by Fortinet back in July of 2014.  And to progress from that blog post, back in 2013, Dion showed how conservative garbage  collectors used by script engines can be attacked to leak information about heap addresses.  So does memory protection provide a new surface for a similar attack?  That's an interesting idea.  In a sense, memory protection acts like a conservative garbage collector freeing allocated  memory only if no references are found on the stack.  This means that it might be susceptible to an attack similar to the garbage collection  attack done by Dion.  The key idea here is that when memory protection examines values on the stack, it doesn't understand  anything about the semantics of those values.  It treats each D word as if it is potentially a pointer.  So if we'd like, we can plant a chosen value on the stack and memory protection will interpret  it as a pointer.  Memory protection will then exhibit different behavior depending on whether or not the integer  that we chose corresponds to an address of white listed memory.  Here we see a block of memory that is white listed.  So let's say we plant an integer value on the stack and then trigger the memory protection  reclamation routine.  If the integer that we planted corresponds to an address anywhere within the block, then  memory protection will respond in one way and by keeping the block on the wait list.  But if the integer we planted is not within the wait listed block, then memory protection  will behave in a different way and it will deallocate the block.  So it's starting to sound like we may have a way to reveal information about the layout  of the address space.  We can repeatedly guess an address, plant it as an integer on the stack, and get memory  protection to behave in a way that reveals whether or not we have correctly guessed the  address of a certain targeted block in memory.  In other words, we have an oracle.  Or do we?  Because at this point, there's still a very big problem.  Let's take a look at the programmatic contract that's exposed by memory protection.  Aside from that DLL notification, which is not something that gets called during normal  program operation, memory protection does not ever return even a single piece of data from  any of its methods.  That's a problem.  We can influence memory protection based on whether we've guessed the correct address  or not, but to have an oracle, we need to have the ability to read some kind of response  back.  And memory protection's API gives us absolutely nothing.  What this means is we need a side channel.  So when I was thinking about this, the first thing that came to mind was that maybe we  could use a timing attack.  Then something else came along.  It was in the summer of 2014, and some cases started coming into ZDI that were kind of  unusual.  We were seeing proof of concept code that would expose bad code paths in the Internet  Explorer by subjecting the browser to memory pressure.  The code would do some lengthy loop doing repeated DOM manipulations and also consuming  memory.  And at some point when address space was nearly exhausted and memory allocations were starting  to fail, a code path would be triggered that was vulnerable.  It was striking how a reasonably reliable trigger could be constructed in this way,  even though the browser process was under such a high level of stress.  I started to think about the idea of operating the browser in a regime of high memory pressure.  It's relatively unexplored territory.  What kinds of things can we make happen?  It struck me as interesting.  Something else I noticed was that when script requests an operation that requires a heap  allocation and the allocation fails due to lack of available memory, the script receives  an out of memory exception.  Here we have a way for attackers script to detect whether an allocation was a success  or a failure.  All it needs to do is check for the exception.  Here's the crucial insight.  Script can detect whether an allocation succeeds or fails.  Whether it succeeds or fails is a function of the existing state of the heap.  In other words, JavaScript out of memory exceptions are a side channel that reveals information  about the state of the heap.  That's exactly the side channel we need in order to get information back from memory  protection.  Here's the high level view of how we consult the memory protection oracle.  Don't be concerned about the exact details.  I'm going to get to that just a bit later.  For now, let's appreciate the high level structure of what we're going to do.  Say we have a block of memory on the memory protection wait list.  We want to consult the oracle to determine whether a certain address, X, is an address  that falls within the block.  We plant X on the stack as an integer and then we do something that triggers the reclamation  routine.  In response, memory protection modifies the heap in a way that's dependent on whether  X points within the targeted block.  How do we find out how memory protection has responded?  We attempt a heap allocation that is designed to either succeed or fail depending on what  memory protection has done to the heap.  Then by checking for the presence or absence of an out of memory exception, we can make  a deduction about how memory protection has behaved and then this reveals the answer to  whether X falls within the targeted block of memory.  Here's the whole chain of deductions we make.  Presence or absence of an out of memory exception tells us something about the state of the  heap.  The state of the heap tells us something about how memory protection behaved and how memory  protection behaved tells us whether X falls within the targeted block.  That's the high level view.  Clearly to actualize all this, it's going to take some pretty careful setup.  Here's the thing.  Going back to something I mentioned earlier, once you start thinking about what you can  do in a regime of high memory pressure, some really interesting possibilities open up.  Before going any further though, I'd like to refine what we mean by high memory pressure.  It's more subtle than just piling on lots of pressure until there's almost no memory  left.  First of all, it's not really available memory we're talking about.  It's availability of address space.  In a 32-bit process, the limiting factor that's going to cause allocation failures is not  memory exhaustion, it's address space exhaustion.  The next thing to note, it's possible for allocations to fail even if there's plenty  of address space left.  It all just depends on how large of an allocation you're asking for.  Also, it's not the aggregate amount of remaining address space that matters.  It's whether a large enough contiguous free region can be found.  Let's refine our idea as follows.  Operating the browser in a regime of limited availability of large contiguous regions  of free address space.  Let's play with this a little bit.  Suppose we spray the heap with one megabyte allocations until all address space is consumed.  Then we free one of those one megabyte blocks.  What's left is a one megabyte hole.  That hole is going to be the one and only contiguous region of one megabytes of free  addresses.  Actually, you can leave lots of smaller holes also.  But it doesn't change the fact that we have exactly one hole that's one megabyte big.  Now we go back and we make one more one megabyte allocation.  We know it will be placed right in that hole because that's the only place it can fit.  We can actually keep doing this over and over, allocating a one megabyte block and freeing  it, allocating a one megabyte block and freeing it.  Every single time it's going to be allocated in exactly the same place.  What happened if one time we tried to make that allocation but it failed?  What would that tell us?  What could make that happen?  One thing that could make that happen is if some other allocation went up and came around  and occupied that hole.  But let's say we can rule that out because we know there are no other big allocations  going on.  What would that tell us?  We might be able to conclude that what happened was that the last time that we freed the one  megabyte allocation, it never really got freed because memory protection was holding  on to it.  We have a way of telling whether the hole is free or occupied by trying to make a new  one megabyte allocation and checking to see if an out of memory exception is thrown.  Now we have all the main pieces in place to make an attack possible.  First we prepare memory so there's just one large contiguous free region, let's say one  megabyte in size, but it could be any size we like.  We're going to call that the hole or the region.  What we're going to try to do is use memory protection as an oracle to determine where  that hole is in memory.  So we're going to guess an address X and we want to consult the oracle to determine if  X falls within the hole.  What we're going to do is first we'll make a one megabyte allocation so now the hole  is occupied.  Next we're going to free that allocation, meaning that it gets passed to protected free  and protected free puts the allocation on the wait list.  As far as the windows heat manager is concerned the memory is still allocated.  Then we're going to plant X as an integer on the stack and while X is there on the stack  we're going to do something that triggers memory reclamation.  Now what happens next depends on whether X falls within this one megabyte address region  or not.  If X falls within the address region then when memory protection performs reclamation  it will keep this allocation on the wait list and it won't free it on the heat manager  level.  Otherwise if X doesn't fall within the region then memory protection will remove this allocation  from the wait list and invoke heat free which completely deallocates that block.  So this shows the two possible states that we can end up in.  If X falls within the region then the hole stays occupied but if X does not fall within  the region then the hole gets opened up again.  Last step to tell which of these two states we just ended up in all we need to do is make  one more one megabyte allocation.  If it succeeds we know that the hole got opened and this means that X wasn't within the region  but if we get an out of memory extension then we know that the hole stayed occupied which  tells us that X falls within the region.  Now we have an answer from the oracle and then by repeating this process with different  values of X we can use the oracle to find out exactly where this one megabyte hole is  in memory.  Now I'm going to go back to this idea just one more time when we operate the browser  in a regime of limited availability of contiguous regions of free address space the new possibilities  that arise can be quite interesting and actually is going to lead us to what we can do next.  So far what we have is a way to prepare the address space so there's just one large hole  of available addresses of a size of our choosing and then to use the memory protection oracle  to determine the exact addresses of that hole.  How can we make good use of this ability?  What can an attacker gain from knowing the address of a hole in the address space?  We can load a module into it.  We can start by creating a hole that's exactly the right size for loading a particular module  then using the memory protection oracle we leak the address of the hole finally we cause  the loading of the module.  It gets loaded exactly at the beginning of the hole because that's the only place where  it's going to fit.  So it's actually an SLR bypass and it runs really efficiently and reliably we're going  to show a demo video here what it looks like to run.  This is a fully patched IE.  On that demo video it's got the address already popping up.  And there it is.  Okay, so this has been a lot of fun.  It started out looking like something that was non-exploitable turned out in the end  to be a reliable SLR bypass.  The key insight that made it possible is that JavaScript out of memory exceptions are a side  channel that reveals critical information about the state of the heap.  I don't think it's been recognized before.  There are really interesting possibilities that open up when you operate the browser  under memory pressure.  Okay, so we've made several recommendations to Microsoft for ways that it can improve  isolated heap and memory protection to harden them against the attacks we've discovered.  In regard to memory protection we've seen how in various situations the attacker can benefit  from the ability to make precision modifications to the state of memory protection.  And we've even shown that this leads to a breakdown of ASLR.  To make memory protection resistant to attempt to normalize and to control its state we make  the recommendation to remove memory protection from array and buffer allocations.  This means that memory protection would apply only to scalar allocations.  Our rationale is that one almost never finds an exploitable use after free condition in  Internet Explorer where the freed object is an array or a buffer.  On very rare occasion we have seen UAF cases submitted to a zero-day initiative where the  freed object is some sort of string data.  But in every case these have turned out to be non-exploitable conditions.  And since UAFs of arrays and buffers in Internet Explorer are rare to non-existent, the benefit  of applying memory protection to these allocations is doubtful.  On the other hand we've demonstrated how it can be a very significant benefit to an  attacker with air-fulfill that memory protection will be a stronger defense if applied to scalar  allocations only.  Our next suggestion pertains to strengthening ASLR.  Taking a look at how we got ASLR to fail, what you can notice is that the attacker was  able to violate one of ASLR's assumptions by preparing the address space in a particular  way.  Do you know Diozovi made a similar observation when he said, thinking about security mitigations  like DEP and ASLR designed for service-ide code doesn't work when you give your attacker  an interpreter.  So I feel that ASLR needs to be strengthened for the browser because the browser is an  inherently more hostile environment.  Here's the particular assumption that ASLR makes that when it chooses a load address  for a module from among the set of possible load addresses that this random choice will  exhibit a significant amount of entropy.  But an attacker can break this assumption by radically narrowing the set of possible  load addresses before the module loads.  Our recommendation is to enhance ASLR by adding an additional check before loading a module.  This check is to ensure that there really do exist a multiplicity of addresses at which  the requested module could load before actually performing the random selection of a load  address.  If the number of possible load addresses is below a certain threshold, the module load  should fail.  Since loading the module under this circumstance could significantly weaken the security of  the entire process.  Ideally this mitigation would be implemented at the kernel level and it could be made available  on an opt-in basis for executables such as browsers which are a more hostile environment  as we mentioned.  It would also be possible to implement this mitigation in user-land code at the application  level by hooking the relevant system calls.  Here's a quick-site sequence diagram showing how the entropy check works.  The application requests the module to be loaded.  Kernel examines how many places of memory available for the module to load.  Kernel decides that the minimum threshold is met and it proceeds to choose one of the  possible load addresses at random, loads the module, and it returns success to the caller.  While the kernel is responding to the module load request, it locks changes to the address  space to prevent a time of check, time of use attack.  Another time the application requests the module to be loaded.  Kernel examines how many places of memory available for the module to load.  This time the kernel detects that there are too few possible load addresses.  The kernel denies the module load request, returns failure to the application, and it  shows the locking that takes place during the second request.  Next recommendation is regard to out-of-memory exceptions.  We've shown that JavaScript out-of-memory exceptions are a side channel that reveals information  about the state of the heap.  Although this leaked bit of information might seem insignificant at first, we have a very  good idea of how it can be leveraged to great effect.  It should also be mentioned that out-of-memory exceptions greatly aid the attacker in setting  up conditions of memory pressure that are needed for our ASLR bypass attack, as well  as triggering other vulnerabilities that are dependent on memory pressure.  We therefore recommend considering eliminating out-of-memory exceptions in script.  When an allocation fails due to memory or address space exhaustion, instead of passing  an exception up to script code where it can be handled, the condition should be considered  as fatal to the process, or at least fatal to script execution within the process.  This seems unlikely to have a significant negative impact upon legitimate web pages  and web applications.  Finally, we recommend taking ISO heap to the next logical step by creating additional  separate heaps.  Ideally one could have a separate heap for each scalar type.  This would bring two great benefits.  First, a use-after-free condition could never lead to type confusion, since every type is  confined to its own heap.  Secondly, since each heap consists entirely of objects of homogenous size, misalignments  will not arise.  Actually, this last point is made trickier by storage of C++ arrays, because C++ arrays  can introduce misalignment, because when an array is stored, the individual elements don't  have heap metadata added to them, the way that heap metadata is added to the individual  scalar allocations, and plus the C++ compiler adds some metadata of its own to store the  arrays' dimensions.  It's actually possible to use C++ arrays to introduce misalignment into heaps.  However, as we've mentioned, exploitable UAFs in arrays and buffers are extremely rare  in Internet Explorer, so we recommend just leaving all array and buffer allocations on  the default heap instead.  If we do that, it should become impossible for an attacker to produce misalignments on  the isolated heaps.  Actually, there's another completely separate reason why it's best to leave arrays and buffers  on the main process heap.  I'd like to digress a moment to explain why.  There's something that doesn't get much attention when iso-heap is discussed, and that's what  we could be called an address-reuse attack.  What's that?  Well, consider how iso-heap is supposed to ensure that when a DOM object is freed, then  an attacker won't be able to allocate some other non-dom type object in its place, such  as a string.  Iso-heap tries to ensure this by making sure that DOM allocations and string allocations  don't happen on the same heap.  But here's the thing.  The attacker doesn't care about heaps.  The attacker only cares about addresses.  Is it possible for the address of a freed DOM object to later on be the address of a  string allocation?  Well, this would become possible if, say, the iso-heap, which is the heap on which DOM  objects are stored, sometimes relinquishes control of virtual address space that it  no longer needs.  That would create the opportunity for those same addresses to later become part of a different  heap, such as a process heap.  And a string could be allocated there.  Is this attack actually possible?  Currently, this attack is not possible.  Here's why.  The way the Windows heap manager works with small allocations is that it puts them inside  regions of virtual memory called heap segments.  And once a particular heap reserves a segment, it never relinquishes control of those virtual  addresses.  For as long as that heap lives, it's never going to allow those addresses to become part  of any other heap.  And today, the iso-heap is used only for small-scalar allocations, so it's good.  But if instead, i.e., tried to protect large buffer allocations by placing them on the iso-heap,  then isolation wouldn't be guaranteed.  For large allocations, the heap manager doesn't use heap segments.  When the heap manager freed the buffer, it would relinquish control over the virtual  addresses involved, and later on, those virtual addresses could become part of a different  heap, breaking the isolation.  So what this means for us is that it's pointless using Windows heap manager to try to protect  buffers and arrays by placing them on an isolated heap.  That isolation could be easily broken using an address reuse attack.  The bottom line is, best way is to keep array and buffer allocations on the default heap  and have a separate isolated heap for every type of scalar allocation.  Then those isolated heaps will be completely immune to type confusion and misalignment  issues.  So having a separate heap for every scalar type is highly beneficial, but the drawback  is that it may be too wasteful of address space in a 32-bit process where address space  is a scarce resource.  We're faced with a trade-off between security and address space usage.  What can we do to make the best of this trade-off?  We're only going to be able to create a limited number of heaps.  How can we make things as hard as possible for an attacker using only a limited number  of heaps?  In whatever way we make assignments of types to heaps, an attacker who has discovered a  UAF on one particular heap will try to construct an exploit via type confusion and or misalignment  by making use of the various types that we have assigned to that same heap.  Unless we randomize the assignments between heaps and types, we can break the monoculture  of heap partitioning and instead random partitioning at process startup time.  Denies to the attacker the ability to write a reliable exploit that relies on knowledge  of which types are co-located on a heap.  It optimizes the defender's advantage when we make the trade-off between security and  the number of heaps we're willing to create.  Here's how randomized heap partitioning can function.  At process startup time, the process creates a certain configured number of heaps.  This number should be chosen based on the trade-off between security and address space  usage.  Then, it allocates an array having one element corresponding to each scalar type in the application.  The initialization code then populates each element of the array with a heap handle chosen  at random from among the available heaps.  Then, whenever application code performs a heap allocation of a particular scalar type,  just looks up the appropriate heap handle in the array and uses that heap and the same  applies to the allocation.  We expect that randomized heap partitioning will make exploits a lot messier because the  types that are needed for type confusion and or misalignment are never guaranteed to be  on the heap that the attacker needs them to be on.  Exploit reliability will suffer as a result.  Failed exploit attempts typically result in process crashes, making attacks easier to  detect.  This means that ODays in the wild can be discovered and patched more quickly.  Also the attacker gains no knowledge from crashes since a new randomization is done with every  process startup.  In some randomized heap partitioning, CIM serves to minimize the benefit that the attacker  can hope to attain relative to the cost of discovering UAFs and developing and fielding  exploits for them.  To recap the new defenses we are recommending, remove memory protection from arrays and buffers.  Strengthen ASLR by making a positive check for entropy in load address selection.  After eliminating JavaScript out of memory exceptions, create one heap type in 64-bit  processes.  Use randomized heap partitioning in 32-bit processes.  All right.  So just kind of a little bit of conclusion.  Of course we have many use after freeze coming into our program.  We have attacks against isolated heap.  We have attacks against memory protection and an ASLR break.  So why not put it all together into an exploit?  So we did that for the bounty submission.  So not that most of us have not seen a IEA exploit before, but at the time it was the  latest patched IEA.  And what you're going to see it do is it's going to run and break ASLR.  It will say retry once and then it will get the load address and then exploit the use after  free vulnerability and pop calc.  So we can chain this with one of the many sandbox escapes that we know about in IEA  to do some damage.  So we are releasing all of the research that we did for the Microsoft bounty program.  It's actually up on GitHub right now.  I just checked.  We've released the white paper that we submitted to Microsoft.  We have proof of concepts up there for the memory protection and isolated heap stuff.  We have put ASLR bypasses up that targets Windows 7, IEA 11 in default configuration.  We've also uploaded a ASLR bypass that works against Windows 8.1, IEA 11 in default configuration  up there because they decided not to fix it even though we provided quite a bit of recommended  defenses.  So in conclusion, this research was a lot of fun.  We got to kind of come at it from another side.  We're usually the ones deciding how much to pay for vulnerabilities and exploits.  And in this case, we put our research up to another company to judge it.  And so it was an interesting experience.  We learned a lot going through it.  I really had a good experience with Microsoft dealing with them.  So this is where we sit today.  Are there any questions?  Yes?  Hello.  Do you have any technique for avoiding LFH after users in some indeterminate state of  browsing?  This can be a little bit tricky.  I don't think there's a generic way to do it, but it's solely bug-specific.  Hey, some of those slides read patent pending.  Are these mitigations encumbered by patents?  Some of them are patent pending.  For Microsoft, specifically with the way that the bounty program works, the release's rights  to them to use them all.  Thanks.  My memory protection technique does not apply to 64-bit processes.  Any other?  All right.  Thank you for your time.  Enjoy playing with the proof of concepts.  Thank you.
recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_0_1043.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_1044_5159.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_5160_6311.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_6312_9695.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_9696_11051.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_11052_15215.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_15216_17279.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_17280_20339.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_20340_21803.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_21804_24287.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_24288_26099.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_26100_26807.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_26808_26963.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_26964_28391.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_28392_28871.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_28872_32471.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_32472_35699.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_35700_43151.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_43152_44579.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_44580_46643.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_46644_47207.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_47208_52775.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_52776_57563.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_57564_57659.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_57660_58067.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_58068_58187.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_58188_58235.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_58236_58619.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_58620_58667.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_58668_58715.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_58716_59039.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_59040_59183.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_59184_59879.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_59880_60263.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_60264_60311.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_60312_60443.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_60444_60563.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_60564_60887.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_60888_60959.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_60960_61235.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_61236_61283.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_61284_61739.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_61740_61787.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_61788_61883.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_61884_62015.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_62016_62159.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_62160_62483.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_62484_62699.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_62700_65807.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_65808_66059.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_66060_66287.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_66288_66359.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_66360_66455.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_66456_66563.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_66564_66923.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_66924_67019.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_67020_78167.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_78168_78227.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_78228_78479.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_78480_78575.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_78576_78623.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_78624_78779.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_78780_78899.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_78900_79103.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_79104_79151.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_79152_79451.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_79452_79703.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_79704_79751.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_79752_79931.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_79932_80231.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_80232_80303.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_80304_80507.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_80508_82667.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_82668_84671.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_84672_84779.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_84780_84851.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_84852_87911.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_87912_87959.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_87960_91067.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_91068_93755.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_93756_93875.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_93876_94067.png recon2015-02-brian-gorenc-simon-zuckerbraun-abdul-aziz-hariri-Abusing-Silent-Mitigations_94068_94110.png
Alright everybody, this is abusing silent mitigations, understanding internet explore, weaknesses in internet explorers, isolated heap and memory protection mitigations. We've got a lot to cover so we're just going to dive right in. So today we're going to go over a comprehensive set of research we did in mid-2014 related to the isolated heap and memory protection mitigations that were introduced to make UAF exploitation harder on internet explorer. It'll cover several attack techniques against isolated heap, some surgical tools to use against memory protection along with details over the ASLR bypass that was generated using memory protection. Then we'll follow it up with some, with the recommended defenses that we provided Microsoft. This research was awarded $125,000 from Microsoft's Bounty Program. It still is the highest payout from the Microsoft Bounty Program. It also included the first payout for the defenses side of the Bounty Program and we're going to go over all of those details today. So a quick overview, we all work for HP Zero Day Initiative Program. It's the world's largest vendor agnostic bug bounty program. We focus on purchasing vulnerabilities from researchers all over the world. We focus on getting those bugs fixed. We research advanced exploitation techniques. My name is Brian Gorance. I actually run the Zero Day Initiative Program. I spend most of my time doing root cause analysis on cases that come in doing internal vulnerability discovery. I also organize the PONDA own hacking competitions around the world. Because of those jobs, I get to work a lot with HP's legal organization, especially with the Wastner and stuff like that. Doing PONDA own is a lot more fun than it used to be. And the introduce Abdul. So I'm Abdul. I'm a security researcher working for ZDI. I've been working for HP Security Research for the past two years. And I do a lot of root cause analysis and bug discovery. Simon? Hi, I'm Simon Zuckerbrunn. On Twitter, I'm Hex Kitchen. I'm with ZDI. I've been with them for a little over a year. I do a lot of work with Internet Explorer. Yes. So it should be no surprise to anybody in this room that use after free vulnerabilities were a very popular choice for attackers who were targeting government websites and people who were visiting those sites and using them in watering hole attacks. But what you see here on the slide is a bunch of CDEs that were being used publicly or known about publicly. I mean, and really something had to be done. Every single month, it seemed that new attack was coming out that was leveraging a use after free and Internet Explorer. And finally, Microsoft did do something in mid-2014 to make attacking use after free vulnerabilities a little bit harder. And as a result, it seems that attackers have shifted away from use after free and Internet Explorer and are now focusing on flash vulnerabilities. So what exactly happened? Well, in MS-14035, they introduced isolated heap, which Abdul will go over. And the month following that, they introduced memory protection, which was a nice introduction to Internet Explorer to make use after free harder to exploit. The side effect that it had really was it made, i.e., fun to research again. We were receiving a lot of use after free vulnerabilities into the Zero Day Initiative program. And it was pretty much, you know, you hit the website and use after free happens, relatively easy to analyze, relatively easy to exploit. And this gave us, made it more fun to actually go and analyze those cases, made it a little more complicated. So this is the first time that we've ever actually like shown some of our submission trends into the program. And you can see we're kind of over 2012, 2013. You know, we've got, you know, in the teens kind of coming into the program every month, vulnerabilities into Internet Explorer. And we see a spike in early 2014. And this is because researchers all around the world were developing DOM fuzzers and basically sending their output to us for purchase. And so we kind of, for several months there, we're doing about 40 cases, high 30s every month analyzing, purchasing and submitting to Microsoft. And you see in mid 2014, the, a kind of a drop, and that's when isolated heap and memory protection came out. And we've kind of leveled off around 25 Zero Days in IE, coming through our program every month. So it keeps us busy. IE is one of our main, main vulnerability sources. Kind of talking about the research timeline a little bit before we dig into the attacks. You can kind of see all the key dates related to the research. I think some of the more important dates is we had the isolated heap of proof of concepts generated basically in under 10 days post the patch. Same with the surgical tools that we're going to use against memory protection. In the cases where it can be used, we're developed in under 10 days. We had our first working ASLR bypass for against memory protection or using memory protection in early September. We were awarded the $125,000 in November. And we kind of waited to disclose any of the details while we worked out payments to charities. We donated all of the money that we were, we won from the Bounty Program to three STEM organizations to encourage research and engineering. And we made the public announcement in February. The, in April, Microsoft came to us and said that they would not fix the issue, issues that we've discovered and would not be using any of the recommended offenses that we provided. So here we are sitting today at Recon, releasing all the details and all the proof of concepts that we've provided. So we'll talk about where to get all those at the end of the presentation. And so I'm going to hand it over to Abdul. He's going to go over all of the research related to isolated heap. So isolated heap was introduced in June 2014. So back then we noticed that there's a new heap created with a heap created API, Windows API. So basically the main purpose of isolated heap was allocating a lot of DOM objects, moving them to an isolated region, basically providing some kind of separation of DOM allocations against other type of allocations. This was really interesting from an exploitation point of view because it made things hard harder. As the classical ways of overriding freed objects like using strings and stuff like that would not apply anymore to a lot of DOM objects because they have been isolated, moved to a separate heap. And the classical string allocations are kept in the process heap. So basically just like any other mitigation, isolated heap is not perfect. Basically it does a good job by isolating certain allocations, but at the same time it allocates all the DOM objects in one heap. So basically an attacker can free one of these objects and then override it with whatever he wants, whatever type he wants. So basically this makes it clear that there's a type confusion issue here. That attacker can also override that object with another object of a different size so it doesn't have to be a specific of the same exact size so it can be smaller or bigger. So the attacks on isolated heap are very specific, like bug specific. Basically it's highly dependent on the offset being referenced at crash time. So most of the attacks that I'm going to be discussing in my next slides will be related to the type confusion issues and other misalignment issues. So the first attack I'll be discussing is the aligned allocation attack technique. Basically it's not just like you have a free isolated object, you free it and you allocate another isolated object at the same exact spot. But the only challenge here is that what type of object that you would actually allocate instead of that object. This scenario or this attack works well when you have a bug that or you just have to feel that actually the reference is a high offset. So basically you can always choose or find another object that you can control certain offsets like high offsets, certain values or have partial control of. To have this attack working properly we need to put a low fragmentation heap. The reason for that is that we're probably going to be allocating objects of different sizes so we don't want to end up having these allocations on different buckets so we want to have it on the same exact bucket. So the simplest way to achieve this is like in nutshell we have to trigger some freeing conditions like we have to free that specific object. Then in case we want to allocate like a bigger object we have to trigger like massage the heap in order to free multiple chunks, multiple free chunks. Later on we have to call us all the free chunks together in one big chunk. Then we have to space certain objects or replace that specific object with whatever object we want. We can do it with a bigger object, we can do it with a smaller object, it doesn't matter. It depends whatever scenario we have. And finally it's going to be like reusing or trigger their use. So this is my fancy graph here. It shows we have a C table row object and up front we have a C DOM text node. These are isolated basically in this specific example. The C table row, the fee happens on that specific object and then what we did is we overrode it with a C DOM text node. So the reason why we chose a C DOM text node is that in that specific case the bug was referencing I guess offset 30 and the C DOM text node contains an interesting value at offset 30 that we can partially control. So this is the Wendie bug dump, it's a before and after. Basically it shows the C table row before being freed and overwritten. And later on we overrode it with a C DOM text node. Highlighted in yellow is the offset that we're targeting. So basically C DOM text node contains a that specific offset 40000, which can be sprayed. So basically we partially control that offset. So this is a crash time. So when we have a successful overwrite and then we do reference everything, we're going to have a crash time, it's the referencing 40000 as you guys can see. So from there an attacker can spray that address and then control the flow of execution. So the second attack technique that I'll be discussing is the misaligned allocations attack technique. The aligned attack technique works well for high offsets, but in case we have a user after feed that references a low offset that can be kind of problematic. Because we don't have a lot of choices when it comes to DOM objects that we can overwrite it with and have specific low offsets that we can control or partially control. So basically the idea is if we have an object that's allocated at let's say address X, then we have to probably start allocations at X minus n. And then we're going to have one of the objects at X minus n being misaligned against the original object and then we're going to trigger a use and we're going to have an offset being referenced from the misaligned object. So the simple steps are basically influence the heap to call us a lot of free chunks together and then have them like in one big free chunk. Later on we have to spray random objects inside that big free chunk, but in a way that we're going to have one of the objects misaligned against the original object. And later on we're going to trigger the reuse and have it reference something from the misaligned object. So again this is my fancy graph here. Basically we have a C table row. At the front we have a C button, button object. Both are isolated. Then this bug targets the C table row object. Basically what we did is we freed a whole bunch of objects, coalesced all the free chunks together in one big chunk and then we started spraying random objects and then at a specific spot we had the C button misaligned against the original C button row. Basically then dereferencing an offset from the C button row. So basically if you bug dereferencing let's say offset X from C table row you're going to have it dereferencing something different. It's not the same offset from C button. So basically in a nutshell we need to stabilize the heap in a way to produce the same exact free chunk of the same size every time and then we're going to have to spray it with random objects. Basically in my specific example we were able to stabilize the heap with this specific code. It's not a generic code to always produce a free chunk of the same size, but it was like bug specific. It worked every time. In that specific example we had EDI pointing to the middle of the free chunk and later on we're going to see how it works. The free chunk is of size 110. It was always producing the same 110 free chunk. So as you guys can see this is a crash time. EBX comes from EDI. EDI points to the middle of a big free chunk of size 110. Later on we're going to see when we get control. So assuming that we were able to stabilize the heap in a way to give us the same free chunk of the same size every time then we would need to actually spray it with a bunch of objects. In this specific example I chose to target to have a misaligned C button object because at a certain offset it contains a value that I can spray. We can do it in a bunch of ways. We don't have to do it with a C button. Someone can argue that they can do it with a text area and then set some coordinates and you're going to have it working. But the idea here is just to have a misaligned object against the original object. This one worked well though. So this is a crash time. Actually we had EDI plus one C pointing to one two C zero zero four zero zero. It lands on that specific value which is an offset of the misaligned C button object. And as you guys can guess this value can be sprayed easily and then we can gain control. So in a nutshell just to wrap it up. Isolated heap does a good job isolating certain objects from other allocations. It's not perfect. Still have a lot of type confusion issues. It still have misalignment issues. Attacking isolated heap depends on several factors. It's more bug specific. We have to avoid low fragmentation heap as much as possible. And it depends on the offsets that being dereferenced. So I'm going to give it back to Brian to discuss memory protection. All right. So memory protection was introduced in July of 2014 and months after that. I think the patch the month after that they made some improvements to memory protection. What we noticed in the zero day initiative is we were analyzing cases and when that July patch came out we started to see that the cases that we hadn't purchased yet were turning into null pointer dereferences which was really interesting to us. And so we dig more into that and we found memory protection messing with the use after freeze that we were looking at. So we have to figure out what exactly is memory protection. Memory protection is a delayed frame mechanism inside of Internet Explorer and its purpose is to prevent blocks from being deallocated when they're referenced either on the stack or in processor registers. It keeps these blocks in a zeroed out state so that they're unusable and it adds it to a wait list. And every so often a reclamation process will occur. It will go through that wait list of objects and free them at the heap manager level. And so the way that they actually implemented this is instead of calling heap free on these objects they would call protected free on these objects instead. So we kind of need to understand how the heap, how the protected free function works. So the first thing that it does when protected free is called is it checks the wait list and checks to see if it's full. If the wait list is full it will go ahead and process the reclamation sweep, cleaning up the objects that are no longer referenced. After that it will add that block to the wait list and it will zero out and return to the user. If the wait list is not full, which is the case almost all of the time, it will check the aggregate size of the blocks on the wait list. If that aggregate size is over 100,000 bytes it will then perform a reclamation sweep, add the block to the wait list, zero it out and return to the caller. If for example the threshold has not been met it will add the block to the wait list without performing the reclamation sweep. It will zero out the block and return to the caller. So when we look at this the most important thing that we need to know about this function is we can ignore the first check as an attacker because we have control of what protected free actually the allocations that are going on. What we're going to focus on is the 100,000 byte threshold. What we're going to, the most important thing to know is that the reclamation sweep always occurs before the block is, a new block is added to the wait list and that's what we're going to leverage later on when we're trying to free at the heat manager level certain use after free conditions. What exactly is the reclamation process? Well there's that wait list which contains an entry for every block that has been requested to be deallocated and in that entry you've got the block base address, you have the block size and you have a flag that determines whether it's on the isolated heap or the process heap. It will iterate through those entries on the wait list and check the, check to see if there are any references to that object on the stack. It will check to see if there's any references to that object in the processor registers and if there is then the block is wait listed or continues to be wait listed. So after the reclamation sweep the block will still be there, still be zeroed out, still be allocated and can't be used by the attacker. If the references don't exist then we have the object will be freed at the heap manager level and released back. So in the cases where in a use after free where there is a reference on the stack or in the processor registers the memory protection is highly effective. It will keep those blocks allocated so that you can't allocate something underneath them and reuse them in a malicious way. So the, but there's that subset of use after freeze that aren't referenced anymore but there's still, memory protection is still changing the way that the application actually operates and so it causes them some challenges. So what are the challenges that memory protection presents an attacker for the subset of use after freeze that are no longer being referenced? Well first there's the deallocation delay and this is because there's that reclamation sweep that we're waiting for to perform before it would actually get deallocated. So there's several non-determinism that exists because of memory protection. First is the non-determinism produced by what we're calling stack junk which could be non-pointers or stale pointers that are left over in stack buffers that are not clear to their former use. It may just so happen that those stale pointers or values that are on the stack could point into an object that you want to be deallocated but because that stack junk exists the memory protection will not free that object. There's also complexity determining deallocation time due to the number of objects on the wait list so your timing could be off along with complex heap manager behavior due to reordering of the wait list which will result in unstable stack conditions which you kind of need for certain UAF situations. So what can we do? Well the first elementary attack technique is just the generic memory pressuring loop that's been used and used after freeze for a long time to force garbage collection where we'd allocate over 100,000 bytes worth of objects and then we would free them, force reclamation and clear it out. Well that definitely defeats the deallocation delay challenge but it doesn't stop the non-determinism challenge that exists due to memory protection. When we submitted this paper back in October of 2014 there was an unconditional reclamation step when WND PROC was entered to service a message on the threads main when WND PROC is actually entered. The this unconditional reclamation step post September 2014 was rendered non-functional by Microsoft and so this attack technique no longer works which was basically to delay execution of the exploit until that event happened and that unconditional reclamation supercured. Now used after freeze are sometimes timing based and so you need to, this doesn't always work but because Microsoft basically rendered it non-functional it really doesn't matter but for record it's there. So what do we want to do? We want to be able to remove the non-determination, we want to be able to delay deallocation and so what are we going to rely on? Well we're going to rely on the fact that memory protection first checks the size of the wait list and before it performs a reclamation sweep and only afterwards does it add that current block to the wait list. So when you call protected free on block at address A, A will definitely not be reclaimed on that call but it will definitely be on the wait list when the call is complete. So we're going to leverage that fact to make sure we can organize our calls in a way that will guarantee that we deallocate block, a block that we want to use and use after free. We're also going to rely on the fact that the isolated, that the, it doesn't matter which heap the object is on, it can be on the isolated heap or the processed heap. So step one, we want to be able to prep the wait list and we're going to do this by finding a method to trigger arbitrarily sized buffer allocations. So when we find that method, we'll allocate a buffer of 100,000 bytes. We will then free that buffer which because the wait, because the wait list, because of protected free and the way that it operates, it will add that block to the wait list and at this point we know the next time we call protected free, it will then free the blocks that are ready to be reclaimed. So you can kind of see that's the state of the wait list. At the point we have a set of blocks X on the wait list that are waiting to be freed. If they're not referenced anymore, then there's a block of 100,000 bytes that guarantees we hit the reclamation step on the next call of protected free. So we're going to trigger another block and the purpose of this, these steps is to get the wait list into a known state and an approximate size. So we're going to trigger the allocation of a block of size F. We're going to free that block which protected free will be called on that object and reclamation step will be performed because we've reached that threshold of 100,000 bytes. It will go through and iterate through that wait list freeing any block that's no longer referenced by the application on the stack or the process registers and it will also free block A which will bring the wait list into a consistent state and a good size. After all the freeing is done, it will add block B which will bring that wait list to a consistent size and at this point we have a good idea of what the wait list actually looks like. So next we're going to set up the freeing of block C which is the object that we want to perform our use after free attack on and our purpose now with these steps is to cleanly deallocate block C with the minimal amount of additional heap operations. So we call it, we free object C which calls protected free. We no longer are over the threshold so it adds the block to the wait list. Then we allocate that 100,000 byte block. We free that block but because we're not at the wait list, we're not at the threshold yet, it will add it to the wait list. We will then allocate another block which will put us over the wait list and trigger the reclamation step on the next call to protected free and at this point when we call free on object E, we will be freeing object C and object D and reliably. We know then exactly when we're able to deallocate block object C. We can then use the isolated heap techniques that Abdul talked about to perform our use after free attack against object C. You can see what the wait list looks at that point. But we need that method for arbitrarily allocating objects and arbitrarily freeing objects. We can't really rely on sysalloc string or sysfree string based string buffers because they don't use protected free and that's what we need. So in this case, Cster comes to our aid in MSHTML and we can use the DOM method, get elements by class name and in that method, it will create a Cster using the string value passed in and then later it will deallocate using protected free that string. And that's what we're going to use for the arbitrary allocation and deallocation of objects and manipulating the wait list and memory protection. To do this, you actually have to do a priming procedure against the DOM object and we'll talk about it in a second. And really the only limitations to this is the fact that there is a limitation on the size of the object. The smallest buffer you can use in Cster is 56 hex but there is no upper limit so we can be guaranteed that we're going to hit that threshold of 100,000 bytes in that check inside of protected free. So what does the code look like? Well, this is it. Pretty simple. First, we're going to create an object, a DOM object. We're going to call, the priming procedure is basically calling get elements by class name with the string that you're going to use later and keeping a reference to the returned value then any other subsequent call to get elements by class name using that string will reliably allocate a Cster at a size and deallocate that same object using protected free. And as a result, we can now take the steps that we laid out previously to reliably deallocate an object that is not completely mitigated by memory protection. We'll show you a video of one of the proof of concepts that we provided Microsoft of one of the cases that we had submitted, one of our researcher cases that we took to controlling a register. Basically it's using that get elements by class name technique to reliably deallocate that object and then using the isolated heap techniques, the aligned allocations that Abdul talked about to get control of the register, the EIP register. So now I'm going to hand it over to Simon and he will go over bypassing ASLR and also all the recommended defenses. Okay, in this section we're going to talk about how we were able to abuse memory protection to get a bypass of ASLR. So after I got comfortable with these techniques of making precision modifications to the memory protection state, I went back and I started thinking some more about something I'd read in a blog post by Fortinet back in July of 2014. And to progress from that blog post, back in 2013, Dion showed how conservative garbage collectors used by script engines can be attacked to leak information about heap addresses. So does memory protection provide a new surface for a similar attack? That's an interesting idea. In a sense, memory protection acts like a conservative garbage collector freeing allocated memory only if no references are found on the stack. This means that it might be susceptible to an attack similar to the garbage collection attack done by Dion. The key idea here is that when memory protection examines values on the stack, it doesn't understand anything about the semantics of those values. It treats each D word as if it is potentially a pointer. So if we'd like, we can plant a chosen value on the stack and memory protection will interpret it as a pointer. Memory protection will then exhibit different behavior depending on whether or not the integer that we chose corresponds to an address of white listed memory. Here we see a block of memory that is white listed. So let's say we plant an integer value on the stack and then trigger the memory protection reclamation routine. If the integer that we planted corresponds to an address anywhere within the block, then memory protection will respond in one way and by keeping the block on the wait list. But if the integer we planted is not within the wait listed block, then memory protection will behave in a different way and it will deallocate the block. So it's starting to sound like we may have a way to reveal information about the layout of the address space. We can repeatedly guess an address, plant it as an integer on the stack, and get memory protection to behave in a way that reveals whether or not we have correctly guessed the address of a certain targeted block in memory. In other words, we have an oracle. Or do we? Because at this point, there's still a very big problem. Let's take a look at the programmatic contract that's exposed by memory protection. Aside from that DLL notification, which is not something that gets called during normal program operation, memory protection does not ever return even a single piece of data from any of its methods. That's a problem. We can influence memory protection based on whether we've guessed the correct address or not, but to have an oracle, we need to have the ability to read some kind of response back. And memory protection's API gives us absolutely nothing. What this means is we need a side channel. So when I was thinking about this, the first thing that came to mind was that maybe we could use a timing attack. Then something else came along. It was in the summer of 2014, and some cases started coming into ZDI that were kind of unusual. We were seeing proof of concept code that would expose bad code paths in the Internet Explorer by subjecting the browser to memory pressure. The code would do some lengthy loop doing repeated DOM manipulations and also consuming memory. And at some point when address space was nearly exhausted and memory allocations were starting to fail, a code path would be triggered that was vulnerable. It was striking how a reasonably reliable trigger could be constructed in this way, even though the browser process was under such a high level of stress. I started to think about the idea of operating the browser in a regime of high memory pressure. It's relatively unexplored territory. What kinds of things can we make happen? It struck me as interesting. Something else I noticed was that when script requests an operation that requires a heap allocation and the allocation fails due to lack of available memory, the script receives an out of memory exception. Here we have a way for attackers script to detect whether an allocation was a success or a failure. All it needs to do is check for the exception. Here's the crucial insight. Script can detect whether an allocation succeeds or fails. Whether it succeeds or fails is a function of the existing state of the heap. In other words, JavaScript out of memory exceptions are a side channel that reveals information about the state of the heap. That's exactly the side channel we need in order to get information back from memory protection. Here's the high level view of how we consult the memory protection oracle. Don't be concerned about the exact details. I'm going to get to that just a bit later. For now, let's appreciate the high level structure of what we're going to do. Say we have a block of memory on the memory protection wait list. We want to consult the oracle to determine whether a certain address, X, is an address that falls within the block. We plant X on the stack as an integer and then we do something that triggers the reclamation routine. In response, memory protection modifies the heap in a way that's dependent on whether X points within the targeted block. How do we find out how memory protection has responded? We attempt a heap allocation that is designed to either succeed or fail depending on what memory protection has done to the heap. Then by checking for the presence or absence of an out of memory exception, we can make a deduction about how memory protection has behaved and then this reveals the answer to whether X falls within the targeted block of memory. Here's the whole chain of deductions we make. Presence or absence of an out of memory exception tells us something about the state of the heap. The state of the heap tells us something about how memory protection behaved and how memory protection behaved tells us whether X falls within the targeted block. That's the high level view. Clearly to actualize all this, it's going to take some pretty careful setup. Here's the thing. Going back to something I mentioned earlier, once you start thinking about what you can do in a regime of high memory pressure, some really interesting possibilities open up. Before going any further though, I'd like to refine what we mean by high memory pressure. It's more subtle than just piling on lots of pressure until there's almost no memory left. First of all, it's not really available memory we're talking about. It's availability of address space. In a 32-bit process, the limiting factor that's going to cause allocation failures is not memory exhaustion, it's address space exhaustion. The next thing to note, it's possible for allocations to fail even if there's plenty of address space left. It all just depends on how large of an allocation you're asking for. Also, it's not the aggregate amount of remaining address space that matters. It's whether a large enough contiguous free region can be found. Let's refine our idea as follows. Operating the browser in a regime of limited availability of large contiguous regions of free address space. Let's play with this a little bit. Suppose we spray the heap with one megabyte allocations until all address space is consumed. Then we free one of those one megabyte blocks. What's left is a one megabyte hole. That hole is going to be the one and only contiguous region of one megabytes of free addresses. Actually, you can leave lots of smaller holes also. But it doesn't change the fact that we have exactly one hole that's one megabyte big. Now we go back and we make one more one megabyte allocation. We know it will be placed right in that hole because that's the only place it can fit. We can actually keep doing this over and over, allocating a one megabyte block and freeing it, allocating a one megabyte block and freeing it. Every single time it's going to be allocated in exactly the same place. What happened if one time we tried to make that allocation but it failed? What would that tell us? What could make that happen? One thing that could make that happen is if some other allocation went up and came around and occupied that hole. But let's say we can rule that out because we know there are no other big allocations going on. What would that tell us? We might be able to conclude that what happened was that the last time that we freed the one megabyte allocation, it never really got freed because memory protection was holding on to it. We have a way of telling whether the hole is free or occupied by trying to make a new one megabyte allocation and checking to see if an out of memory exception is thrown. Now we have all the main pieces in place to make an attack possible. First we prepare memory so there's just one large contiguous free region, let's say one megabyte in size, but it could be any size we like. We're going to call that the hole or the region. What we're going to try to do is use memory protection as an oracle to determine where that hole is in memory. So we're going to guess an address X and we want to consult the oracle to determine if X falls within the hole. What we're going to do is first we'll make a one megabyte allocation so now the hole is occupied. Next we're going to free that allocation, meaning that it gets passed to protected free and protected free puts the allocation on the wait list. As far as the windows heat manager is concerned the memory is still allocated. Then we're going to plant X as an integer on the stack and while X is there on the stack we're going to do something that triggers memory reclamation. Now what happens next depends on whether X falls within this one megabyte address region or not. If X falls within the address region then when memory protection performs reclamation it will keep this allocation on the wait list and it won't free it on the heat manager level. Otherwise if X doesn't fall within the region then memory protection will remove this allocation from the wait list and invoke heat free which completely deallocates that block. So this shows the two possible states that we can end up in. If X falls within the region then the hole stays occupied but if X does not fall within the region then the hole gets opened up again. Last step to tell which of these two states we just ended up in all we need to do is make one more one megabyte allocation. If it succeeds we know that the hole got opened and this means that X wasn't within the region but if we get an out of memory extension then we know that the hole stayed occupied which tells us that X falls within the region. Now we have an answer from the oracle and then by repeating this process with different values of X we can use the oracle to find out exactly where this one megabyte hole is in memory. Now I'm going to go back to this idea just one more time when we operate the browser in a regime of limited availability of contiguous regions of free address space the new possibilities that arise can be quite interesting and actually is going to lead us to what we can do next. So far what we have is a way to prepare the address space so there's just one large hole of available addresses of a size of our choosing and then to use the memory protection oracle to determine the exact addresses of that hole. How can we make good use of this ability? What can an attacker gain from knowing the address of a hole in the address space? We can load a module into it. We can start by creating a hole that's exactly the right size for loading a particular module then using the memory protection oracle we leak the address of the hole finally we cause the loading of the module. It gets loaded exactly at the beginning of the hole because that's the only place where it's going to fit. So it's actually an SLR bypass and it runs really efficiently and reliably we're going to show a demo video here what it looks like to run. This is a fully patched IE. On that demo video it's got the address already popping up. And there it is. Okay, so this has been a lot of fun. It started out looking like something that was non-exploitable turned out in the end to be a reliable SLR bypass. The key insight that made it possible is that JavaScript out of memory exceptions are a side channel that reveals critical information about the state of the heap. I don't think it's been recognized before. There are really interesting possibilities that open up when you operate the browser under memory pressure. Okay, so we've made several recommendations to Microsoft for ways that it can improve isolated heap and memory protection to harden them against the attacks we've discovered. In regard to memory protection we've seen how in various situations the attacker can benefit from the ability to make precision modifications to the state of memory protection. And we've even shown that this leads to a breakdown of ASLR. To make memory protection resistant to attempt to normalize and to control its state we make the recommendation to remove memory protection from array and buffer allocations. This means that memory protection would apply only to scalar allocations. Our rationale is that one almost never finds an exploitable use after free condition in Internet Explorer where the freed object is an array or a buffer. On very rare occasion we have seen UAF cases submitted to a zero-day initiative where the freed object is some sort of string data. But in every case these have turned out to be non-exploitable conditions. And since UAFs of arrays and buffers in Internet Explorer are rare to non-existent, the benefit of applying memory protection to these allocations is doubtful. On the other hand we've demonstrated how it can be a very significant benefit to an attacker with air-fulfill that memory protection will be a stronger defense if applied to scalar allocations only. Our next suggestion pertains to strengthening ASLR. Taking a look at how we got ASLR to fail, what you can notice is that the attacker was able to violate one of ASLR's assumptions by preparing the address space in a particular way. Do you know Diozovi made a similar observation when he said, thinking about security mitigations like DEP and ASLR designed for service-ide code doesn't work when you give your attacker an interpreter. So I feel that ASLR needs to be strengthened for the browser because the browser is an inherently more hostile environment. Here's the particular assumption that ASLR makes that when it chooses a load address for a module from among the set of possible load addresses that this random choice will exhibit a significant amount of entropy. But an attacker can break this assumption by radically narrowing the set of possible load addresses before the module loads. Our recommendation is to enhance ASLR by adding an additional check before loading a module. This check is to ensure that there really do exist a multiplicity of addresses at which the requested module could load before actually performing the random selection of a load address. If the number of possible load addresses is below a certain threshold, the module load should fail. Since loading the module under this circumstance could significantly weaken the security of the entire process. Ideally this mitigation would be implemented at the kernel level and it could be made available on an opt-in basis for executables such as browsers which are a more hostile environment as we mentioned. It would also be possible to implement this mitigation in user-land code at the application level by hooking the relevant system calls. Here's a quick-site sequence diagram showing how the entropy check works. The application requests the module to be loaded. Kernel examines how many places of memory available for the module to load. Kernel decides that the minimum threshold is met and it proceeds to choose one of the possible load addresses at random, loads the module, and it returns success to the caller. While the kernel is responding to the module load request, it locks changes to the address space to prevent a time of check, time of use attack. Another time the application requests the module to be loaded. Kernel examines how many places of memory available for the module to load. This time the kernel detects that there are too few possible load addresses. The kernel denies the module load request, returns failure to the application, and it shows the locking that takes place during the second request. Next recommendation is regard to out-of-memory exceptions. We've shown that JavaScript out-of-memory exceptions are a side channel that reveals information about the state of the heap. Although this leaked bit of information might seem insignificant at first, we have a very good idea of how it can be leveraged to great effect. It should also be mentioned that out-of-memory exceptions greatly aid the attacker in setting up conditions of memory pressure that are needed for our ASLR bypass attack, as well as triggering other vulnerabilities that are dependent on memory pressure. We therefore recommend considering eliminating out-of-memory exceptions in script. When an allocation fails due to memory or address space exhaustion, instead of passing an exception up to script code where it can be handled, the condition should be considered as fatal to the process, or at least fatal to script execution within the process. This seems unlikely to have a significant negative impact upon legitimate web pages and web applications. Finally, we recommend taking ISO heap to the next logical step by creating additional separate heaps. Ideally one could have a separate heap for each scalar type. This would bring two great benefits. First, a use-after-free condition could never lead to type confusion, since every type is confined to its own heap. Secondly, since each heap consists entirely of objects of homogenous size, misalignments will not arise. Actually, this last point is made trickier by storage of C++ arrays, because C++ arrays can introduce misalignment, because when an array is stored, the individual elements don't have heap metadata added to them, the way that heap metadata is added to the individual scalar allocations, and plus the C++ compiler adds some metadata of its own to store the arrays' dimensions. It's actually possible to use C++ arrays to introduce misalignment into heaps. However, as we've mentioned, exploitable UAFs in arrays and buffers are extremely rare in Internet Explorer, so we recommend just leaving all array and buffer allocations on the default heap instead. If we do that, it should become impossible for an attacker to produce misalignments on the isolated heaps. Actually, there's another completely separate reason why it's best to leave arrays and buffers on the main process heap. I'd like to digress a moment to explain why. There's something that doesn't get much attention when iso-heap is discussed, and that's what we could be called an address-reuse attack. What's that? Well, consider how iso-heap is supposed to ensure that when a DOM object is freed, then an attacker won't be able to allocate some other non-dom type object in its place, such as a string. Iso-heap tries to ensure this by making sure that DOM allocations and string allocations don't happen on the same heap. But here's the thing. The attacker doesn't care about heaps. The attacker only cares about addresses. Is it possible for the address of a freed DOM object to later on be the address of a string allocation? Well, this would become possible if, say, the iso-heap, which is the heap on which DOM objects are stored, sometimes relinquishes control of virtual address space that it no longer needs. That would create the opportunity for those same addresses to later become part of a different heap, such as a process heap. And a string could be allocated there. Is this attack actually possible? Currently, this attack is not possible. Here's why. The way the Windows heap manager works with small allocations is that it puts them inside regions of virtual memory called heap segments. And once a particular heap reserves a segment, it never relinquishes control of those virtual addresses. For as long as that heap lives, it's never going to allow those addresses to become part of any other heap. And today, the iso-heap is used only for small-scalar allocations, so it's good. But if instead, i.e., tried to protect large buffer allocations by placing them on the iso-heap, then isolation wouldn't be guaranteed. For large allocations, the heap manager doesn't use heap segments. When the heap manager freed the buffer, it would relinquish control over the virtual addresses involved, and later on, those virtual addresses could become part of a different heap, breaking the isolation. So what this means for us is that it's pointless using Windows heap manager to try to protect buffers and arrays by placing them on an isolated heap. That isolation could be easily broken using an address reuse attack. The bottom line is, best way is to keep array and buffer allocations on the default heap and have a separate isolated heap for every type of scalar allocation. Then those isolated heaps will be completely immune to type confusion and misalignment issues. So having a separate heap for every scalar type is highly beneficial, but the drawback is that it may be too wasteful of address space in a 32-bit process where address space is a scarce resource. We're faced with a trade-off between security and address space usage. What can we do to make the best of this trade-off? We're only going to be able to create a limited number of heaps. How can we make things as hard as possible for an attacker using only a limited number of heaps? In whatever way we make assignments of types to heaps, an attacker who has discovered a UAF on one particular heap will try to construct an exploit via type confusion and or misalignment by making use of the various types that we have assigned to that same heap. Unless we randomize the assignments between heaps and types, we can break the monoculture of heap partitioning and instead random partitioning at process startup time. Denies to the attacker the ability to write a reliable exploit that relies on knowledge of which types are co-located on a heap. It optimizes the defender's advantage when we make the trade-off between security and the number of heaps we're willing to create. Here's how randomized heap partitioning can function. At process startup time, the process creates a certain configured number of heaps. This number should be chosen based on the trade-off between security and address space usage. Then, it allocates an array having one element corresponding to each scalar type in the application. The initialization code then populates each element of the array with a heap handle chosen at random from among the available heaps. Then, whenever application code performs a heap allocation of a particular scalar type, just looks up the appropriate heap handle in the array and uses that heap and the same applies to the allocation. We expect that randomized heap partitioning will make exploits a lot messier because the types that are needed for type confusion and or misalignment are never guaranteed to be on the heap that the attacker needs them to be on. Exploit reliability will suffer as a result. Failed exploit attempts typically result in process crashes, making attacks easier to detect. This means that ODays in the wild can be discovered and patched more quickly. Also the attacker gains no knowledge from crashes since a new randomization is done with every process startup. In some randomized heap partitioning, CIM serves to minimize the benefit that the attacker can hope to attain relative to the cost of discovering UAFs and developing and fielding exploits for them. To recap the new defenses we are recommending, remove memory protection from arrays and buffers. Strengthen ASLR by making a positive check for entropy in load address selection. After eliminating JavaScript out of memory exceptions, create one heap type in 64-bit processes. Use randomized heap partitioning in 32-bit processes. All right. So just kind of a little bit of conclusion. Of course we have many use after freeze coming into our program. We have attacks against isolated heap. We have attacks against memory protection and an ASLR break. So why not put it all together into an exploit? So we did that for the bounty submission. So not that most of us have not seen a IEA exploit before, but at the time it was the latest patched IEA. And what you're going to see it do is it's going to run and break ASLR. It will say retry once and then it will get the load address and then exploit the use after free vulnerability and pop calc. So we can chain this with one of the many sandbox escapes that we know about in IEA to do some damage. So we are releasing all of the research that we did for the Microsoft bounty program. It's actually up on GitHub right now. I just checked. We've released the white paper that we submitted to Microsoft. We have proof of concepts up there for the memory protection and isolated heap stuff. We have put ASLR bypasses up that targets Windows 7, IEA 11 in default configuration. We've also uploaded a ASLR bypass that works against Windows 8.1, IEA 11 in default configuration up there because they decided not to fix it even though we provided quite a bit of recommended defenses. So in conclusion, this research was a lot of fun. We got to kind of come at it from another side. We're usually the ones deciding how much to pay for vulnerabilities and exploits. And in this case, we put our research up to another company to judge it. And so it was an interesting experience. We learned a lot going through it. I really had a good experience with Microsoft dealing with them. So this is where we sit today. Are there any questions? Yes? Hello. Do you have any technique for avoiding LFH after users in some indeterminate state of browsing? This can be a little bit tricky. I don't think there's a generic way to do it, but it's solely bug-specific. Hey, some of those slides read patent pending. Are these mitigations encumbered by patents? Some of them are patent pending. For Microsoft, specifically with the way that the bounty program works, the release's rights to them to use them all. Thanks. My memory protection technique does not apply to 64-bit processes. Any other? All right. Thank you for your time. Enjoy playing with the proof of concepts. Thank you.
with the recommended defenses that we provided in MS-14035, they introduced isolated heap, which vulnerabilities into Internet Explorer. And we memory protection. In the cases where it can be a separate heap. And the classical string one heap. So basically an attacker can free one being referenced at crash time. So most of the was basically to delay execution of the exploit free will be called on that object and aid in MSHTML and we can use the DOM method, get And as a result, we can now take the steps that protection provide a new surface for a similar something else came along. It was in the summer as an oracle to determine where that hole is in use the memory protection oracle to determine the gain from knowing the address of a hole in the possible is that JavaScript out of memory additional check before loading a module. This module to be loaded. Kernel examines how many our ASLR bypass attack, as well as triggering on which DOM objects are stored, sometimes guaranteed to be on the heap that the attacker patent pending. Are these mitigations encumbered