Buffer Overflows – what they are and how they work.
This can be quite a complicated issue, so I will try to break it down into different parts and put it into everyday language.
I will assume that if you are reading this you understand a little programming (functions, integers etc)
To understand buffer overflows it helps to know a bit about how a program utilizes memory.
First it will help to understand what an EIP is:
[it is essential to understand an EIP to understand how a buffer overflow works]
Extended Instruction Pointer.
The processor has a very small chunk of memory itself, divided into what is called registers.
The most common register is the EIP; this tells the processor where to look in the system memory for the function (or piece of code) that it has to execute.
I.e. the code could be to print the word antionline on to your monitor and has been written to the memory at the address of 0x12345678. (Memory uses the hex numbering system).
The EIP would now tell the processor to go to 0x12345678 and do what ever the code is telling it to do, hence the word “antionline” will be printed on the screen.
There are five types of program memory, text, heap, stack, bss and data.
Each one of these is a special piece of memory reserved for a certain type of purpose.
I will cover text and stack for the purpose of this paper.
This is where the compiled machine language is stored. Write permissions are disabled here as it is used only to store the code, which is being executed.
When you compile a program, what you are doing is converting it from human readable form into a language the computer understands, it is the output of a compiled program that is stored in the text segment)
So for a very simplified example say you wanted to print the words Hello, goodbye, thank you, and Microsoft rules
(For ease I will use 1,2,3,4,5 etc for memory addresses instead of the correct addresses.
So hello is stored at 1, goodbye at 2, thank you at 3 and Microsoft rules at 4.
Here is what the processor will do
1. Get the address for the first function to complete from the EIP and go there
2. Add the number of bytes in the instruction to the EIP
3. Do what ever the piece of code is telling it to do, (print Hello.)
4. Go back to the EIP to get the next address.
The EIP will know when the instruction has been completed because in step 2 the processor told it how many bytes there was.
The stack memory is used as a tempory storage space for functions.
When a function (print) is called by a program it will have its own variables (hello,goodbye,thank you etc)
and the code will be at a different place in the text segment of memory.
(I.e. hello cannot be at the same memory address as goodbye otherwise they would over write each other.)
So the function is to print Hello (1) Goodbye (2) and Thank you (3)
The whole function will be read from the text segment and get passed to the stack segment.
The stack segment will remember the addresses (1,2,3) of each variable and pass this data to the EIP to tell it which memory address to return to when the function is finished.
There is a lot more to the stack segment but it’s not really relevant at this point!
Ok, so the programmer has specified that the word Hello with need 5 bytes of memory, but what happens when 7 characters try to write them selves to this piece of memory instead, the word goodbye for example:
|H|E|L|L|O| – No probs here
1 2 3 4 5
|G|O|O|D|B| —— |Y|E| – | – | – | – They overflow into memory held for something else
-1- 2- 3-4-5 —— -6- 7- 8- 9 – 0
5 bytes are allocated but the variable was 7 bytes long. Now it can’t just disappear, it has to be written somewhere so a buffer overflow occurs. If the data that was overwritten in 6 + 7 were a critical part of the program, the program would have crashed.
Here is a well know piece of code to cause a buffer overflow (its very well known and is in most books about the subject, so know one jump on my back for posting it, please)