Stack Corruption for Newbies

This tutorial will be a fun one; we're going to explore how the hacking of software works. A hack, in general terms, is a trick that allows us to make a system (program in this case) do something that it wasn't intended to. I wrote a small application for this tutorial that we will attack. This program is vulnerable to a technique called a buffer overflow which we'll be employing to break it. This guide was written with the complete beginner in mind. Even if you've never written a line of code before, I hope to explain how the security of software can be compromised in a way that is understandable. If something is unclear, please shoot me an email and I'd be happy to explain further.

The vulnerable program source code - Download a C compiler such as Dev-C++ if you want to experiment further.
The vulnerable program - Use Start->Run "cmd" and then "cd [folder where this file is]" then type "vuln1" to run.

The Target

To the left we see the source code for the program we are attacking. Programmers write source code and then compile it to produce executable programs. We'll now do a quick step through of what each line means.

include [stdio.h] tells the compiler that we want to use some of the functionality already coded in the file stdio.h (like being able to read from the keyboard).

int main() { } is the function that Windows calls when this program is run. A function is just a block of code; calling it cause the code inside to execute.

char correct = 'N'; creates a variable that stores a character/letter. It then fills this variable with the letter 'N'

char password[10]; creates a variable that stores 10 characters. This is also called a buffer. It then fills this buffer with the letters "NOTHINGYET"

gets(password) calls the function gets with the argument password. Basically, it makes the program wait for the user to type something and hit enter. This typed info is then stored in the password buffer. All of this fancy keyboard code is found in stdio.h

if...else if... These lines of code tests if the variable correct has the letter 'Y'. If it does, it displays "You win!" on the screen, if not it displays "You fail!". It will always say that you fail because, as you can see, there is no code that changes the letter from 'N' to 'Y'. Our goal is to make the program change the 'N' to a 'Y' and tells us that we win.


We will now explore how these variables are stored in memory. Thats all a variable is really; its a place in memory set aside to hold information. When thinking about places in memory, we need to consider a few things. Where is it? How big is it? How the data inside formatted? For now, we won't concern ourselves with the exact locations of these variables; we don't need that information for now. What is important to think about is where these variables are in relation to each other. In our program's case, although it is declared first, the "correct" variable actually comes after the password buffer in memory with some padding in between the two. Different types of variables have different sizes, but the only ones we are dealing with here are char types. A char is one byte (8 bits) and can stored a single alphabetical letter. An array of chars (buffer) like our password variable is simply 10 chars in a row. Data in 32-bit x86 processors likes to be group in 4 byte chunks. Each of these 4 byte chunks stores its bytes in reverse order (this is called Little Endian). This is not a huge deal, but it is important when dealing with this sort of thing. The picture to the left is sort of like a snapshot of what the relevant part of memory looks like right before the user is asked for input and should help clarify what is written here.

Running Properly

Lets walk through how the program runs if a normal user runs it. First, they click Start and then Run. Once the dialog box pops up, they type cd [folder where the app is]. This makes the command prompt navigate to the folder where the vulnerable program is. Then they type vuln1 to run the program. The program creates a letter-sized variable called "correct" and stores 'N' in it. Then it creates a 10-letter long buffer called "password" and stores "NOTHINGYET" in it. Now the program waits for the user to type something and hit enter. The user types the word "PASSWORD" and hits the enter key. The program then checks out the "correct" variable to see if it changed to 'Y': it didn't. There is no way for a normal user to type a correct password make that letter change. The app then tells the user that he failed and exits rudely.


By now, you may be thinking that there is no way we can "win" this game and change that correct variable to a 'Y'. There is a flaw in this program that will allow us to do just that: gets. The gets function does not do any bounds-checking when it takes data from the keyboard and shoves it into a buffer. In order words, it will keep sticking typed characters into memory until the user hits the enter key. It starts this process from the beginning of the password buffer but nothing says it has to stop there. We can type a long stream of letters until the password buffer is full and then continue until we hit spot in memory where "correct" is stored. When we get there, just make sure that the letter typed is the one we want instead of the 'N' this program tells it to be. For example, we can enter AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY and the program will happily report "You win!".

Other Thoughts

What we have done is overflow a buffer on the stack. The stack is the area of memory that a program uses to temporarily store things. Variables that are declared inside functions (like "correct" and "password") are kept on the stack. By typing more letters than the program expected, we were able to overwrite data that we aren't suppose to and make strange things happen. This is a very simple example that allows you see how this process works without worrying about learning the really difficult nitty-gritty details that come with more traditional buffer overflow examples. Hopefully you learned something from it and seek out more information about this very cool topic.