Tuesday, 8 April 2008

Buffer Overflow In Action Tutorial - Part 1

by Mach-0

Tutorial Description : This tutorial will show you how to buffer overflow programs in order to change the flow of the
application , even if this means executing your own code. This is the part one where i show you
how to change the flow of the program ( not execute your own code ), plus i give you all the
code and the compiled ones ( in case you don't have a compiler ) and a video
demonstration/tutorial
Who should read this : Anyone who is interested in computers should read this. Tutorials about security are not meant for
hackers.. their actually meant for the programmers ( and anyone else who likes computers ) so
when they create a program they will know what to do in order to avoid stuff like buffer
overflows , SQL (or anything else ) injections , XSS, Remote file inclusions etc...
A programmer that actually knows this stuff can create a FAR more secure and stable application
than the ones that don't and i find it very stupid for some programmer saying that he doesn't need
to know this.
What is a buffer overflow? Buffer overflow is when you try to put data into an array.. but the data are more than the array
size. The problem occurs when you don't properly check the bounds of the array. So when you
write data in the array it comes a time that the array ends... but you keep writing data in the
memory next to the array, thus overwriting anything else that was there before.
Why can someone
exploit a buffer
overflow problem ? when overwrite the memory data that are out of the array you can overwrite critical for the
application information, like the EIP. EIP (Instruction Pointer) holds the return address so when
the function ends, it while find a ret instruction which will put the program counter at the value
in which EIP is holding. So i you can change that value you can change the program flow and
make it execute something else.
What do you need : For this tutorial you will need :
- OllyDbg : A great debugger
- Bloodshed Dev-C++ : A C/C++ Compiler
- Perl : i wrote the exploit with Perl
- Time , patience , brain and the will to learn
Ok,
let's start... A Buffer overflow occurs when you try to write data into
an array which is smaller than the amount of data you are trying to
write
into, thus overwriting what is after the buffer in the memory. I will
not explain here how the memory structure is when a program/function is
executed.
I will just show you how to exploit it
Let's see a vulnerable program ( vuln.c )
Code: Select all
#include <stdio.h>

int OverflowMe(char *str){

char buffer[10]; //our buffer

strcpy(buffer,str);//the vulnerable command

return 0;

}

int main(intargc, char *argv[])
{
int pass=0;

printf("You are in vuln.exe now\n");

OverflowMe(argv[1]); //call the function and pass user input

if ( pass = = 1) {
GoodPass(); //this should never happen
} else {
printf("Lozer!!!\n");
}

printf("Quitting vuln.exe\n");

return 0;
}


int GoodPass(){

printf("******* You are IN! *******\n");
printf("******* This is GoodPass() executing *******\n");

}
The program above has a problem when strcpy(buffer,str) will be executed with the length
of
the str more than 10 ( array size ) What i am going to show you in this
tutorial is how to change the flow of the program and execute the
GoodPass() function
which normally should never get executed.... Don't forget to see the Video Demonstration to understand it better...
First
we try to crash the program in order to confirm that the buffer
overflow does exist. To do that we run the vuln.exe and give it for
arguments a long string like this : ( 60 A's )
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAA This is
what we get :
Image
Now
the new return address is 41414141 ... which is A ( A is number 65 in
ascii and number 65 is 41 in hex) So what we did is to change the
return address to 41414141 which doesn't exist so windows gives as an
error. What we need to do now is to change that address and make it
point to our GoodPass ( ) function that we want to execute. First we
must find the function's address... to do that we use OllyDbg... ( see
video demonstration how to do it )
Image

So
we want to force the program to execute 00401302 address which is the
call to the GoodPass ( ) function First we have to fix that address...
we must write it in an Little Endian format... So 00 40 13 02 becomes
02 13 40 00 Ok we have the target address for the new EIP... now we
need to find how many bytes are from the start of the buffer until the
actual EIP To do that we must create a long string with random
characters... try not repeating a sequence in the characters so the
four characters you will get when the program crashes will be a unique
sequence in the string so you can find the easily... From experience a
good way to create a string is using hash algorithms.. I have an online
tool that can calculate the hash results for a string using several
algorithms..
click here to go to the Online Hash Calculator page I
made this string : CE6BE5DF0409E4A15BBE3E37FF5B309A54B0C58C7CE9F2A8B5
51351102EE0938FA26BE19DE6BFF93FBDA So what we need to do now is to run
the vuln.exe using the above string as argument
Image
Ok
we got 41393033 as the new EIP... now we must first fix it ( now it's
in Little Endian format ) So 41 39 30 33 .. becomes 33 30 39 41 Now we
find what is the ascii character that each hex number represents
To do this you can go to my ASCII - HEX - Unicode Online Converter Tool and put in the hex field the
above
numbers with a % in front of each one of them... like this %33%30%39%41
and click 'Decode Hex to Ascii' So 33 30 39 41 is the string '309A' in
ascii... now we search for that string in the big string we put for
arguments before...
CE6BE5DF0409E4A15BBE3E37FF5B309A54B0C58C7CE9F2A8B551351102EE0938FA26BE19DE6BFF93FB
DA ok now we will not need anything after the 309A so we discard it..
and the string becomes CE6BE5DF0409E4A15BBE3E37FF5B309A |<----------
28 bytes ----------------->|
In the string above.. if is put for
arguments for the vuln.exe program will overwrite the buffer and
replace the EIP with the value
that is found after the first 28
bytes... so what we must do is to sent for arguments a 28 bytes length
junk data and 4 bytes of evil EIP address... And now we write the
exploit... I wrote the exploit in Perl.. to run it you need to have the
Perl interpreter installed... you can find it in the links i gave you
at the start of the page Here is the code of the exploit ( exploit.pl )
Code: Select all
#!/usr/bin/perl

my $junkdata="\x41"x28;# create the 28 byte length junk data

my $ret="\x02\x13\x40\x00";# our evil EIP goes here

my $exploit=$junkdata.$ret;# merge them into one evil string

print "Sending exploit....\n\n";

system("vuln.exe", $exploit); # execute vuln.exe with the evil argument string


print "\nDone!\n";
So we run the exploit code and the result :
Image
Program flow successfully changes and GoodPass( ) gets executed



No comments:

Post a Comment