Buffer Overflow Attacks Explained: Saved Return Pointer Overwrite

Juni 15, 2016

In today’s Whiteboard Wednesday, David Maloney, Senior Security Researcher at Rapid7, will discussa type of cyber security threat, buffer overflow attacks.

David will walk you through a buffer overflow exploit called “saved return pointer overwrite” to show you specifically how buffer overflow attacks work.

Watch this week’s Whiteboard Wednesday to learn more.


Video Transcript

Hi, welcome to this week's Whiteboard Wednesday. I'm David Maloney, Senior Security Researcher on the Metasploit team here at Rapid7. Previously, we've talked about exploit mitigations that are available on Microsoft EMET and in the following series we're going to go a little more in-depth in those mitigations. But, to start, we need to talk about how some of these exploit techniques work so that we can talk about how we defend against them. 

Show more Show less

This week, we're going to be talking about the saved return pointer overwrite. The saved return pointer overwrite is sort of the main technique for traditional buffer overflow exploits. So, imagine that you have a little program written in C that looks something like this, right here. You've got your main function, which has some function calls, and it calls another function called "do something," and inside that it's got a little buffer over here that we're going to overflow. What happens in memory is you have a construct referred to as the "stack", and the stack grows upwards as you go through the program. So, when we're in the main function here, everything we need for memory that's saved in the stack is saved in this portion of the stack.  

Now, we get to the point where we call do something and a few things happen, a new stack section is created called a "stack frame", and that stack frame is specific for the do something function here. So, you can see, we have our blue section of memory here that corresponds to our main function and then we gain the do something stack frame. In order to set that up though, we need some way of knowing how to get back to this code over here. So, after we finish with do something, we have to know how the program is supposed to get to this next instruction that says to call the do something else method.  

Now, the way a program actually keeps track of what instruction it's on is something called the EIP register. When we jump into a new function, we save a pointer to that next instruction so that it can be loaded into EIP when we're done. So as we go into the do-something method, the current value of the EIP register gets placed onto the stack, in what's called the "saved returned pointer". Then, we build up the rest of this stack frame. We see here that we need a hundred character string for a foo. It allocates a section of memory just big enough to hold that string. This space, right here, is able to hold a hundred A's or other characters in it.  

But what happens if we put more than 100 A's in it? This is where your buffer overflow comes in that you've probably heard about but maybe you don't quite understand how it works. So, what happens is we have this section with just enough space for a hundred A's. But, as we start to write more than a hundred A's, those A's will continue to flow down into this space here, filling all of this up until we get down to here, where the saved return pointer is. What happens when we finish the do something method, is it's going to collapse this whole section of memory, and then take whatever the value here at the saved return pointer is and load it back into the processor register of EIP, and then that's going to tell the program what instruction to execute next. So, if we overflow this all the way down into the saved return pointer we can actually overwrite that value and tell the program an arbitrary place to commit its next execution.  

So, if you imagine, instead of filling this buffer with A's, you were to fill it with actual bite codes that could be interpreted as instructions, when you get down to this part in the saved return pointer, you're going to overwrite that with an address that points way back to the beginning of this section that you wrote, and instead of reading this as data now, what it's going to do is start interpreting it as instructions, and it can execute your shellcode. This is the basis of how a stack based buffer overflow works. So, a lot of your traditional exploits in Metasploit are based on this principle. We put all our shellcode, which will be our payload, through the buffer, and then continue to overflow until we write a memory location into the saved return pointer, and the program will then change where it executes, executing our shellcode and giving us a shell usually.  

So, that's about it for this week. We'll see you on next week's Whiteboard Wednesday. 

Free Metasploit Trial

What could an attacker do with your vulnerabilities? Find out with a free trial of our pen testing software.

Download Now