Prerequisites :
-Knowledge of how computers manage their memory, how the stack segment works at least.
-Basic Linux Command-line knowledge
-Basic knowledge on a few Assembly operation\instructions and their operands(we'll be working with intel syntax opposed to AT&T (You probably know Intel, most debuggers use it at default))
-How to compile things in linux with GCC via terminal\console
-Basics C++ programming knowledge
A working version of Linux with
-GCC
-GDB
-Python (Command-line at least.)
All the above came with my linux bootable, and they shoud've come with yours, or at least if it's a modern ubuntu redistribution.
In this tutorial we're going to take advantage of buffer overflows. Usually, when a programming encounters a buffer overflow, its an crappy situation, and it calls for some debugging. Although, you will be surprised how large of a hole an unprotected copy into a buffer can be. Take a look at the following C\C++ code :
[php]
#include <string.h>
int main(int argc,char* argv[])
{
char* argPointer = argv[1];
char buffer[10];
strcpy(buffer, argPointer);
return 0;
}[/php]Despite the fact that this doesn't really do anything, it does open a hole for buffer overflows. Note there is another method you can use called strncpy, which takes an extra parameter, an unsigned int of the max amount of bytes\chars that can be copied. Excluding that note, and provided the programmer of the application you're exploiting uses strcpy, you can exploit this without out even cracking into the code. Compile that and execute the compiled project via the command line with
[php]cd <Directory your compiled code is>
./compiledProject 1234567891[/php] -This will cause the program to execute normally
[php]cd <Directory your compiled code is>
./compiledProject 1234567891111111[/php] -This causes it to crash with a segmentation fault (We'll find a more useful purpose for buffer overflows in a couple of minutes)
Before we can take advantage of this, lets first understand why it crashes, and what C's function-calling convention is. Disassemble this looks like
Assembled code may differ, depends what you used to compile your CC++ code and what version of the compiler.
[php]
1 : push ebp
2 : mov ebp, esp
3 : sub esp, 0x28
4 : and esp, 0xfffffff0
5 : mov eax, 0x0
6 : sub esp, eax
7 : mov DWORD PTR [ebp + 4], 0x8048474
8 : lea eax,[ebp-24]
9 : mov DWORD PTR [esp], eax
10: call 0x80482a0 ;//This is the address of the strcpy method
11: leave
12: ret
[/php]First we're going to talk about what a stack-frame is, how it works, and where it's being setup in this short assembly code, this is more of a review. Whenever a function is called, the particular function needs it's own space in the stack for its local variables, temporary data, or anything that needs to be saved and isn't in the BSS, DATA, or Heap segments, and remember, even though main is what a lot of programmers think of as 'the start' it's still treated as a function. In line 1 of that assembly code, you see push ebp. The EBP register is used as the base pointer for the function's stack-frame. ESP is used to point to the top of the stack, keeping in mind the stack grows to a lower address in memory. For example, EBP may be 0x00000A, but ESP is 0x000002 (just an example, these are not valid memory addresses).
With that said, lets start emulating this function call in our head. When a function is called, in this case, the main function, EIP(Pointer of the next address to be executed) is pushed to the stack, this is because when we use the ret instruction at the end of our function, we pop this address and go to the next instruction eip points to. Then we get to line one, we push EBP, which is the address of the base of our previous stack-frame. This is so we can restore it at the end of our function and set esp back to ebp. At the second line we copy ebp to esp, and then we subtract 28 from from esp to make room for the stack-frame. ESP now points to the top of our newly setup stack frame, and ebp now points to the base of our new stack frame. Remember, as the stack grows, it grows to lower addresses. That's all you really need to know about that for this tutorial, and I have like 30 more minutes to write this before I do some fucking retarded english bullshit homework, soh. Now, our stack looks something like this
Code:
all below addresses are fake.
data]fake address]pointed to by] notes(if any)
]
]
]
]
]
]
]
0x22458622]0x0000FFFC]ESP]pushed ebp first line of function
0x22458611]0x00010000]none]pushed eip before function execution
Now, lets examine the code, ignoring the functions prologue and epilogue.
[php]
5 : mov eax, 0x0
6 : sub esp, eax
7 : mov DWORD PTR [ebp + 4], 0x8048474
8 : lea eax,[ebp-24]
9 : mov DWORD PTR [esp], eax
10: call 0x80482a0 ;//This is the address of the strcpy method
[/php]The main reason we used a pointer to point to argv[1] in the C++\C code, is because the argv parameter in the main function is a pointer to a pointer, and it complicates this part of assembly a little. Anyway, continuing, we can ignore lines five and six because ultimately they have no effect. In line seven, we copy 0x8048474(As a pointer, this is a pointer to the start of our argv[1]) into ebp + 4 (thats the stack frame), then we use the lea instruction, which stands for load effective address, and loads the <Source Param> into the <Destination Param>(lea <source>, <Destination>.) in this case, we're copying the address ebp - 24 to eax. ebp - 24 is the location of our buffer. So now we've setup the stack for the call of strcpy. Now take a look at this inaccurate example of what the stack may look like:
Code:
[Start of our buffer (We're copying into this)
[Space allocated for buffer in stack frame
[Space allocated for buffer in stack frame
[Space allocated for buffer in stack frame
[Space allocated for buffer in stack frame
[Space allocated for buffer in stack frame
[Space allocated for buffer in stack frame
[EBP
[ESP
So here is where it might pop to you how dangerous a buffer over-flow can be. It's where it did for me XD. Anyway, so if we filled this buffer with the appropriate number of characters we allocated for the buffer we'll have something like :
Code:
[A
[A
[A
[A
[A
[A
[A
[EBP
[ESP
And if we filled it with 1 more "A" then we did previously, we'd have :
Code:
[A
[A
[A
[A
[A
[A
[A
[Corrupted EBP pointer
[ESP
And with four more
Code:
[A
[A
[A
[A
[A
[A
[A
[overwritten EBP pointer
[overwritten EIP pointer
How can we take this to our advantage? Well, if we put the appropriate number of bytes in there, say I overflowed the previous C program with enough A's to fill the buffer and reach the area in the stack where I recently push EIP, I could use a series of \x<TwoDigitHex> to create a memory address to overwrite the one pushed in that stack, thus after the function finishes and hits the ret instruction its not going to jump to the address recently pushed by call before the function was executed, but it's going to jump to whatever I overflowed it with.
How can you prevent this? Well you can use strncpy, or just make sure there is no chance of your arrays overflowing. There are probably better ways, but I'm here to teach you how to take advantage of it, not protect yourself from it.
Sorry if the tutorial is hard to follow, I'll come back tomorrow and clean it up, I have a fucka lot of English homework to do, I'll also teach you how to recreate this in C++ code and via the command-line with python(Which can be used to quickly overflow large buffers) if I can get time to work on this tomorrow, anyway, bai.