Saturday, February 10, 2007

Buffer Overrun

Today i will talk about another security issue. Buffer overrun is a dangerous and destructive concept which shouldnt be exist in our codes. It has many forms like stack buffer overruns , heap buffer overruns, index out of bounds, ascii- unicode conflictions. However, i want to explain you only stack buffer overruns and leave the rest to you :)

When we look at the history of computer software, there were millions of dollars costs of these attacks. By using the buffer overflow attacks a hacker can reach lots of valuable informations or can destroy the whole system at once.

Before starting, i want to give some information about the C calling convention.
When we call a C function for a function, the caller function push the parameters to the stack in reverse order so the first parameter will be on the top of the stack and it is popped first. In addition when the called function wants to return to the caller it pops the return address of the caller from the stack and jump to there by taking this address. At this point, you can imagine that if the called function takes the wrong address from the stack, it jumps somewhere different then it shold jump to!

I want to show you with a simple example:
( My code is compiled in unix with gcc. I dont use Visual studio because it makes lots of optimization and has lots of flags which prevent overflow in debug mode )


#include stdio.h
#include string.h

void BufferOverFlow( char* str ){

char buffer[4];

//see the stack
printf("stack looks like: %p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n");

strcpy( buffer , str ); //copy without controlling anything

//see the stack after copying str to buffer
printf("Now stack looks like: %p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n");
}


void Information(){
printf("My credit card number: 333445566\n");
printf("My password: emreknlk\n");
}

int main(){

//last 4byte is the address of information function
char str[12]={1,2,3,4,5,6,7,8,0xb2,0x83,0x04,0x08};

printf("Address of Information:%p\n",Information);

BufferOverFlow(str); //call only BufferOverFlow function


return 0;
}


Lets look at the code. In the main function we simply call the BufferOverFlow function. Normally, we expect that BufferOverFlow function executes its code and returns to main again.
In our application we also have an important function whose name is Information. We dont want to show this function to anyone without permission.
However in the BufferOverFlow function, there is a bufferover flow exists. We dont control the str string while copying it to local variable buffer! buffer can take at most 4 byte because it is an char array of 4 elements, but we give it 12 elements and change the stacks content by overflow. Indeed, we change the return value which is stored in stack too. We give a new value as the Information function address so that BufferOverFlow function returns to Information function and all our data is displayed on the screen!! Look at the output:

-bash-2.05b$ ./buff
Address of Information:0x80483b2 <--This is the information functions address
stack looks like: 0x8e4062 <--Stack content in BufferOverFlow function
0x9caec0
0x80485b1
0xbfff8b48
0x9ccab8
0xbfff8b68
0x804843b <-- This is the return value that we override
0xbfff8b50
Now stack looks like: 0xbfff8b50 <-- After copying str to buffer
0x9caec0
0x80485b1
0xbfff8b48
0x4030201 <-- 1 2 3 4
0x8070605 <-- 5 6 7 8 ( overflow )
0x80483b2 <-- LOOK! the return value has changed! New value
0x9ccab8 is the address of Information!!!
My credit card number: 333445566 <-- Information function executes its body!
My password: emreknlk <-- my credit card and password are in the hackers
Segmentation fault hand :(
-bash-2.05b$

Yes we call another function by hacking the stack. The address of the functions can be obtained by using a debugger. And input parameter can be prepared by inspecting the code by running it with some input paramters.

In this post, we handle the buffer overrun issue. It has many forms and we show an example to stack buffer overflow. For preventing this issue, the code must be robust and safe libraries and functions should be used when coding the application.
See you again.

No comments: