In today’s Whiteboard Wednesday, David Maloney, Sr. Security Researcher at Rapid7, will discuss the ROP exploit technique for buffer overflow vulnerabilities and how to mitigate these security issues.
Watch this week’s Whiteboard Wednesday to learn more.
Hi. Welcome to this week's Whiteboard Wednesday. I'm David Maloney, Senior Security Researcher on the Metasploit team here at Rapid7. And today we're going to be continuing our ongoing series on buffer overflow exploits and the mitigation techniques that help you protect against them. Specifically, we've been discussing exploit mitigations that are provided to you by Microsoft EMET toolkit.Show more Show less
Today, we're going to be talking about a family of mitigation techniques all centered around protection against ROP. So if you caught our previous video on ROP, and this is Return-Oriented Programming, and it's how you typically try to bypass DEP, or Data Execution Prevention, another mitigation technique. Each one of these in and of itself is not a silver bullet. There's really no silver bullet for ROP, but each one of these adds a little bit of the barrier to entry on successfully executing a ROP chain as part of an exploit. So we're gonna go through some of these.
The first one is Mem Prot, or Memory Protection, and if you'll recall from our ROP video, we talked about how your ultimate goal with ROP is to get a call to something like VirtualProtect or VirtualAlloc, which you can use to mark the stack as executable, so you no longer have to worry about DEP. What Mem Prot does is when it detects a call to VirtualProtect, it looks at how that call is being made, and tries to determine whether it's a legitimate use of VirtualProtect or not. And if Mem Prot sees like, oh, this is very obviously being called from inside some shellcode on the stack, then it just goes, "Nope, not allowed to do that." So that's one way that it can do it.
Now, that's not a foolproof way, and it's very difficult still for EMET to say for sure, "Oh, yes, this is definitely shellcode calling this VirtualProtect." So it's of somewhat dubious value, but it is still valuable. Next one is the LoadLibrary protection. This is a little different. So what this does is it prevents a running program from making a call to load a library, one of those DLLs, or sometimes we refer to them as modules, from a file share on like a remote network resource.
So if there's a DLL sitting on like an SMB file share somewhere on the network, and some shellcode is executing this program that says, "Hey, load this library that's on a network resource," one of the reasons you might do this is if you can't build a reliable ROP chain in the program itself, if you can trick it into loading a library from somewhere else as a network resource, then you can have the get ROP gadgets already available from that new library that you forced it to load.
So all LoadLibrary does is it says, "Oh, hey, you're calling LoadLibrary on a file...on a DLL on a file share or on a network resource of some kind." I'm not gonna let you do that either. Next, this one's really simple. How effective it really is is somewhat questionable, but it's called the ROP Caller Check. And this one is another guard on the VirtualProtect, VirtualAlloc, any of those Windows API functions that allow you to change the permissions of a section of memory. So, it triggers when say VirtualProtect is called, it says, "Oh, VirtualProtect is being called. How did we get here? Stop for a second and look back. Did we get this call to VirtualProtect from a return instruction in the assembly?" If we did, it's a very good chance that this VirtualProtect call is actually part of a ROP chain. And again, we're just gonna say, "Nope, not allowed to do that." This is obviously ROP, so this is not a legitimate call to VirtualProtect to change those memory permissions.
Next is Stack Pivoting. We talked very, very briefly about stack pivoting in the ROP video. And what a stack pivot does is essentially move that stack frame we talked about. If you go way back to our first video, you'll remember we talked about how when you move into a new function, a stack frame is created. And the way it does that is it has a pointer to the top and to the bottom of that...the top and the bottom of that stack frame. And what a stack pivot is is just a set of instructions to move the pointer to the top of the stack somewhere where we have more room, so that when our ROP gadgets are executing, all those arguments and those function calls can be put safely on the stack without overwriting the rest of our code on the stack.
So, stack pivot protection is just another guard that just says, "Hey, if I see this instruction happening that looks like it's dramatically moving ESP, which is the top of the stack pointer, and moving it into a different location, that looks suspicious, and I'm not gonna let that happen either," which will really badly damage your ability to successfully use ROP chains to carry out an exploitation.
The last one, and probably one of the most ambitious ones in the whole set, is one that's called ROP Simulate Execution Flow. And that's kind of a mouthful, but basically what it says is this. When I get to something that looks like a ROP gadget, where I hit a return call...So [inaudible 00:05:41] we do our exploit, we hit the first ROP gadget, which is our stack pivot in this example, when we get to the return call that would point to our next ROP...or the pointer to our next ROP gadget, the ROP Simulate Execution flow stops everything for a second, and looks at the next sets of instructions, and basically runs through it.
And you can think of this as like thinking it through in your head, except that program is doing it off on the side, right? And it says, "Hey, before I let you will actually call this return, what's the next couple of things you're going to do?" And if it looks and it sees, well, it's going to return to this pointer, which is going to go and do another like two instructions and then a return, and then another couple instructions and a return, it's going to go, "Okay, looks like ROP to me, right? And it's gonna say, "Nope, I'm gonna stop it right here at this border," and does not let this execution flow go any further.
So this is just five mitigations. None of them by themselves, or even as a group, are necessarily are a silver bullet for stopping the use of ROP and buffer overflow exploits, but each one can make it just a little more difficult for an exploit writer, and means that the person writing that exploit has to be a lot more expert and a lot more careful in how they're developing that exploit. So they're still very useful and valuable things to have. It really reduces the attack surface in your environment.
So, thanks for joining us, and we'll see you next week.