brian e. brzezicki. this tutorial just illustrates the underlying concepts of buffer overflows by...

of 52 /52
Basic theory of buffer overflows Brian E. Brzezicki

Author: christine-powers

Post on 01-Jan-2016

214 views

Category:

Documents


0 download

Embed Size (px)

TRANSCRIPT

Slide 1

Basic theory of buffer overflowsBrian E. Brzezicki

Just the basicsThis tutorial just illustrates the underlying concepts of buffer overflows by way of an extremely simple stack overflowMost buffer overflow concepts derive from these concepts This techniques is for basic understanding, they are not advanced techniquesThis technique described as is will not work in any modern OS due to compiler and OS protections2Key TermsTo understand buffer overflow requires understanding a few terms

IP registerFunctionStack

3IP registerA special memory location directly on the CPU which holds the address in memory of the next instruction to be executedOn Intel IA32 architectures it is called EIPOn Intel IA64 architectures it is called RIP

* if an attacker can set the value of this register, they can direct the CPU to execute their instructions

4StackA data structure in system memory where data is stored temporarilyStacks usually grow down from lower to higher memory addresses, as data is added to the stack

Memory AddressValue1000First stack variable99969992StackA data structure in system memory where data is stored temporarilyStacks usually grow down from lower to higher memory addresses, as data is added to the stack

Memory AddressValue1000First stack variable9996Second stack variable9992StackA data structure in system memory where data is stored temporarilyStacks usually grow down from lower to higher memory addresses, as data is added to the stack

Memory AddressValue1000First stack variable9996Second stack variable9992Third stack variableStackA data structure in system memory where data is stored temporarilyStacks usually grow down from lower to higher memory addresses, as data is added to the stack

Memory AddressValue1000First stack variable9996Second stack variable9992Third stack variableFunctionA small part of a program that performs a specific action or functionPrograms are comprised of many functions

main() { char [8] string;

printf(hi there how are you?); gets(string);} FunctionA small part of a program that performs a specific action or functionPrograms are comprised of many functions

main() { char [8] string;

printf(hi there how are you?); gets(string);} * printf and gets are functionsHow functions use the stackWhen a function is called any parameters passed to the function are added to the stack

add(x,y);printf(hi there);

Memory AddressValue10009996999211How functions use the stackWhen a function is called any parameters passed to the function are added to the stack

add(x,y);printf(hi there);

Memory AddressValue10009996999212How functions use the stackWhen a function is called any parameters passed to the function are added to the stack

add(x,y);printf(hi there);

Memory AddressValue1000y9996999213How functions use the stackWhen a function is called any parameters passed to the function are added to the stack

add(x,y);printf(hi there);

Memory AddressValue1000y9996x999214How functions use the stackAfter the parameters are added to the stack, the memory address of the next instruction after the function is put on the stackadd(x,y);printf(hi there);

Memory AddressValue1000y9996x999215How functions use the stackAfter the parameters are added to the stack, the memory address of the next instruction after the function is put on the stack (return address)add(x,y);printf(hi there);

Memory AddressValue1000y9996x9992address_of printf(hi there);16How functions use the stackAny local variable that the function uses will be placed on the stack after the return address.

sub add(x,y) { int total;

total=x+y; return(total);}

Memory AddressValue1000y9996x9992address_of printf(hi there);17How functions use the stackAny local variable that the function uses will be placed on the stack after the return address.

sub add(x,y) { int total;

total=x+y; return(total);}

Memory AddressValue1000y9996x9992address_of printf(hi there);total18How functions use the stackOnce the function completes, the local variables will be removed from the stack

sub add(x,y) { int total;

total=x+y; return(total);}

Memory AddressValue1000y9996x9992address_of printf(hi there);total19How functions use the stackOnce the function completes, the local variables will be removed from the stack

sub add(x,y) { int total;

total=x+y; return(total);}

Memory AddressValue1000y9996x9992address_of printf(hi there);20How functions use the stackFinally the CPU will load the memory address that is on the stack into the IP register and continue execution at that point

sub add(x,y) { int total;

total=x+y; return(total);}

Memory AddressValue1000y9996x9992address_of printf(hi there);21Finally the CPU will load the memory address that is on the stack into the IP register and continue execution at that point

sub add(x,y) { int total;

total=x+y; return(total);}

How functions use the stackMemory AddressValue1000y9996x9992address_of printf(hi there);IP Register = address_of printf(hi there);22The exploitThe key of an buffer overflow is to get your own code (shellcode) into memoryoverwrite the function return address to point to the memory location of your codeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}Exploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

In this function the line above is vulnerable, as it takes any length input and tries to store it into the location assigned to input which is only 8 bytes longThe stackNow lets look at the memory layout of the stack26Exploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

When the input is read from the user, the data will be stored in the space allocated for the input variable

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

When the input is read from the user, the data will be stored in the space allocated for the input variable

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

When the input is read from the user, the data will be stored in the space allocated for the input variable

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

You could enter your own code when prompted to please enter input

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

You could enter your own code when prompted to please enter input

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968input variable spaceExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

You could enter your own code when prompted to please enter input

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972input variable cont9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

You could enter your own code when prompted to please enter input

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you enter more than 8 characters, you will start overwriting the other data on the stack

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976plea9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you enter more than 8 characters, you will start overwriting the other data on the stack

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980se e9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you enter more than 8 characters, you will start overwriting the other data on the stack

Memory AddressValue1000x9996return address9992ut9988 inp9984nter9980your shellcode9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you enter more than 8 characters, you will start overwriting the other data on the stack

Memory AddressValue1000x9996return address9992ut9988 inp9984your shellcode9980your shellcode9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you enter more than 8 characters, you will start overwriting the other data on the stack

Memory AddressValue1000x9996return address9992ut9988your shellcode9984your shellcode9980your shellcode9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you enter more than 8 characters, you will start overwriting the other data on the stack

Memory AddressValue1000x9996return address9992your shellcode9988your shellcode9984your shellcode9980your shellcode9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

Now youve overwrote the local stack variables if you write more youll overwrite the return address

Memory AddressValue1000x9996return address9992your shellcode9988your shellcode9984your shellcode9980your shellcode9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you put the address of the start of your shellcode, when the function returns the IP will be loaded with the address of your shellcode

Memory AddressValue1000x999699689992your shellcode9988your shellcode9984your shellcode9980your shellcode9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

If you put the address of the start of your shellcode, when the function returns the IP will be loaded with the address of your shellcode

Memory AddressValue1000x999699689992your shellcode9988your shellcode9984your shellcode9980your shellcode9976your shellcode9972your shellcode9968your shellcodeExploitable functioninteractWithUser(int x) { char msg=please enter input; char[8] input;

printf(%s,msg); gets(input); return();}

Then the system will run your shell code instead of returning to the normal program!Memory AddressValue1000x9996return address9992your shellcode9988your shellcode9984your shellcode9980your shellcode9976your shellcode9972your shellcode9968your shellcodeYou control the executionNow you haveSuccessfully input your own code in memoryDirected the system to execute your codeGame Over YOU win!

Additional things to think about / need to solveHow did we know where our shellcodes address is in memory?How do we determine the shellcode?Dont programs generally generaly filter input for un-allowed characters?What happens if the system uses a Non-eXecutable stack / memory or Address Space Layout Randomization (ALSR) referencesSmashing the Stack for Fun and ProfitPhrack issue 49available at http://insecure.org/stf/smashstack.html