In today’s Whiteboard Wednesday, David Maloney, Senior Security Researcher at Rapid7, will share a technique to help mitigate buffer overflow attacks.
In a previous Whiteboard Wednesday, we explained how buffer overflow attacks work. This week, we are going to explain how to help mitigate buffer overflow vulnerabilities with stack cookies.
Watch this week’s Whiteboard Wednesday to learn more.
Hi, and welcome to this week's Whiteboard Wednesday. I'm David Maloney, senior security researcher on the Metasploit team here at Rapid7. Previously, we talked about saved return pointer overwrites for stack based buffer overflow exploits. This week, we're going to talk about the mitigation technique that was at first developed as a way of preventing those kinds of attacks. They're alternatively referred to as stack cookies or somewhat less frequently as a stack canary.Show more Show less
This was one of the first techniques people came up with as a way of preventing those saved return pointer overwrite exploits. It's gone through a lot of different implementations, and there are a lot of different versions of this out there, especially in the Linux world. There have been a lot of improvements and switching around of how we do it. The big takeaway is that Microsoft implementation, which is the /GS compiler flag, has been a default option in their Visual Studio compiler now since 2005. That is on by default in all modern Visual Studio compiled Windows programs.
What a stack cookie seeks to do is prevent that buffer overflow from successfully overwriting the saved return pointer and gaining control of execution. We talked about how by overflowing the foo string here we could write down into the saved return pointer. What happens with the stack cookie is in this stack frame there is a specific value that is calculated and placed onto the stack before the saved return pointer. If we go about our regular exploit technique and start overflowing this buffer, we fill these As and it fills down through the rest of this allocated space. You see we have to pass through the stack cookie in order to get to the saved return pointer. We're writing all of our As or our shell code if we're doing a full on exploit. We overwrite that stack cookie, and then we put our value in the saved return pointer.
It seems great, right? We've got our saved return pointer. When we exit the function and do something, we should jump to that instruction that we've given the address for. The problem is while it's tearing this down it stops and it evaluates the stack cookie. It has a little routine that it's going to go through to check the value of that stack cookie to make sure that it hasn't changed since it placed it on the stack. If it determines that that stack cookie value has actually changed, it's going to stop that thread of execution altogether. While this might not be ideal for the program because it's obviously lost something in it stopped running the routine that it was supposed to be executing, it is better than the alternative which is letting us gain control of the saved return pointer and basically changing how the program works. It's a very primitive first pass mitigation, but it does help make exploits just a little bit more difficult and required the creation of some new techniques that we're going to talk about in future videos.
Thanks for joining us, and we'll see you next week.