____ __ __ ___ ____ | __ ) _ _ / _|/ _| ___ _ __ / _ \__ _____ _ __ / _| | _____ _____ | _ \| | | | |_| |_ / _ \ '__| | | | \ \ / / _ \ '__| |_| |/ _ \ \ /\ / / __| | |_) | |_| | _| _| __/ | | |_| |\ V / __/ | | _| | (_) \ V V /\__ \ |____/ \__,_|_| |_| \___|_| \___/ \_/ \___|_| |_| |_|\___/ \_/\_/ |___/ _____ _ ___ _ | ___|__ _ __ | |/ (_) __| |___ | |_ / _ \| '__| | ' /| |/ _` / __| | _| (_) | | | . \| | (_| \__ \ |_| \___/|_| |_|\_\_|\__,_|___/ by bob [www.dtors.net] [[--Introduction--]] This tutorial is not going to teach you how to code an exploit, but what it is going to do is give you a good understanding of what a buffer overflow is, what types of buffer overflows there are, how we would go about exploiting a buffer overflow, and how to identify a buffer overlow. You do not need to have any knowledge in C or ASM, as I will try my best to explain it to you. This tutorial is aimed at the people that want to get a better understanding of buffer overflows. If you want to start coding your own exploits, or identifying bugs and reporting them, then this is one of the many places you should start. At the end of this tutorial I will put some good references on articles that will help you in this subject. I hope you learn something from this and enjoy the read.....here goes....... [[--Jargon Buster--]] First off, the most annoying thing when reading a tutorial like this, is all the confusing words. Well I intend to get that out the way first, so that you can read this tutorial with complete understanding. exploit: is a program designed to exploit a problem another program may have. The exploit will allow us to run arbitary code that will allow us to do something we shouldnt. buffer: is a block of memory that holds "multiple instances of the same data type." heap: is a space a program reserves for a variable. (You access the heap when you use the malloc() function). stack: is what a program uses to store temporary information such as our return address from a function that the program called, or a local variable. SFP: Stack Frame Pointer. This is the start address of the stack. RET: Return address. This is when a function was called, and the system saved where it was called from. So when the function ends, it will read the return address and let the program return to where is left off. Now if we were to change the return address, we could point it to another address to execute something we shouldnt. [[--What is a buffer overflow?--]] What happens when we try and put a pint of beer into a half pint glass? It OVERFLOWS, it spills everywhere and we waste our damn beer. The technical way to explain this, is to say that a buffer overflow is the result of putting to much data into a buffer than it can handle. So this may lead to us executing arbitary code IF a certain memory pointer is overwritten. Lets do this by example, below will be a program that we will use to demonstrate how this may occur. ---------------------------------cut-here-------------------------- /* * beer.c */ void main() { char pint[10]; char half_pint[1]; memset(pint,0x41,10); strcpy(half_pint,pint); } ---------------------------------cut-here-------------------------- This program trys to put a pint of beer into a half pint glass, like the example I used earlier. For those of you that dont understand C, ill take each line and explain it to you. void main() -- This is our "main" function. char pint[10]; -- This is our first variable called pint. Notice the size of our pint. char half_pint[1]; -- This is our second variable, notice this is 10x smaller than our pint. memset(pint,0x41,100); -- memset fills the variable pint with 0x41 which is hex for the character "a". So think of the a's as our beer. strcpy(half_pint,pint); -- Now we try and put our pint of beer into our half pint glass, but it OVERFLOWS. } -- Function ends. See its really not that hard to understand. We simply try to stuff to much data into a variable. Now during the overflow the SFP and the RET will be overwritten with a's "lots of beer :)". This means that our return address will now be 0x41414141. When our main function exits, the computer will try and execute the instruction at 0x41414141. In this case it will cause an error as it is outside the process space. << ill explain this bit later. So now that we know we can overwrite the RET address, we can go on to exploit it. To do this we would have to point it to our new address where we would instruct it to execute our arbitary code. See how fun this is? One thing I will make clear, is the fact that when trying to overflow a program in most cases, there is no point in doing this unless the program is owned by root and it has suid permissions. If your asking your self "what the hell is this guy going on about now?". Well to explain it a bit clearer, a program must be suid to give you ROOT privileges. SUID? A suid permission is given to a program that may need to perform tasks that normal programs cant do. For example. If as a normal user you tried to edit /etc/passwd, you would get permission denied. BUT if you used the program /usr/bin/passwd, it gives you permissions to edit passwd, in a certain environment that allows you to edit YOUR password only. [[--Different types of buffer overflows.--]] There are two well known types of buffer overflows. One based on the stack, the other on the heap. The most common of the two is the stack based overflow, but now days there are non-executable stack patches. Which will stop stack-based attacks. This is where heap overflows come in handy, we can then actually work around the stack guard. Unfortunatley heap overflows are not very well understood. So to keep things simple for you and ME, we will stick with stack based overflows. I have already given you the definition of what the stack is, and I have shown you a worked example, of how a stack-based buffer overflows occurs. Now im going to go into more details, so hang on, it may get bumpy... Lets make a new Vulnerable program... /* for testing purposes change the function from bob to main */ void bob(){ char beer[10]; gets(beer); } The way the stack works is simple. LIFO: Last in, First off. Doesnt make sense huh? Ok think of bricks of lego. Each time you add one, you put it on top, and when you take one away, it comes off from the top. This may sound confusing...but really its very simple. This is how the stack organises its data. Anyway back to our program, what this program is doing is asking for user input. But if the user inputs over 15 char's, it will overflow, causing a Segmentation Fault. So when our program calls bob() "our function" it will make room for beer[] on the stack. +++++++++++++++++++++ + beer[] + +++++++++++++++++++++ + + + Return Address + +++++++++++++++++++++ + + + + ^^^ This is a primitive example of what the stack will look like. Now our goal is to overwrite beer[] with malicious code... ..when we make beer[] overflow, we can write beyond the end of beer[] and overwrite the RETurn address. What we want to do is overwrite the RET, with the address of beer[] so that when our function bob() finishes, our malicious code will be executed. Lets have a look now at what the stack would look like: +++++++++++++++++++++ + Malicious Code + +++++++++++++++++++++ + + + Address of beer[] + +++++++++++++++++++++ + + + + So bob() will then return to the code in beer[]. Are you still awake? Well if you have got this far, im very sure you would have learnt SOMETHING. [[--Conclusion--]] Almost finished now... Ive given you a basic overview of what a buffer overflow is, how we would exploit it, and how the stack works. There are ways to protect against stack-based overflows, for example, "make sure you use secure functions when using the stack". Also try to make sure you provide methods to deal with the potential dangers of user defined input. To go about finding a buffer overflow is simple. As all of linux, and linux related programs are open source, you can use programs such as FlawFinder to examine the source code. Things Flawfinder checks for are libary funtions that dont perform boundary checking like: strcpy() strcat() sprintf() vsprintf() scanf() getc() and getchar(). You can download FlawFinder at www.packetstormsecurity.org. Thanks for reading, I hope you enjoyed it, and learnt something from this tutorial. [[--Contact--]] My email is bob@dtors.net my homepage is: http://bob.dtors.net [[--References--]] http://www.11a.nu/stack/stack-smash.txt http://www.11a.nu/stack/heaptut.txt http://www.11a.nu/stack/exploit.txt http://www.11a.nu/stack/adv.overflow.paper.txt