Buffer Overflow

31
Buffer Overflow Buffer Overflow

description

Buffer Overflow. Introduction. On many C implementations, it is possible to corrupt the execution stack by writing past the end of an array. Known as smash the stack. It can cause return from the routine to jump to a random address. - PowerPoint PPT Presentation

Transcript of Buffer Overflow

Page 1: Buffer Overflow

Buffer OverflowBuffer Overflow

Page 2: Buffer Overflow

IntroductionIntroduction

• On many C implementations, it is possible to corrupt the execution stack by writing past the end of an array.

• Known as smash the stack.

• It can cause return from the routine to jump to a random address.

• Attackers can control the program flow by sending carefully crafted set of input.

Page 3: Buffer Overflow

Process Memory OrganizationProcess Memory Organization

Text

Data

Stack

LowerMemoryaddresses

HigherMemoryaddresses

Process Memory Regions

Page 4: Buffer Overflow

• Text region– Fixed by the program– Includes code (instructions)– Read only

• Data region– Contains initialized and uninitialized data– Static variables are stored here.

• Stack region– LIFO

Page 5: Buffer Overflow

– Stack is used to• Dynamically allocate the local variables used in

functions.

• Pass parameters to the functions.

• Return values from the function.

– Stack pointer (SP) points to the top of the stack.– The bottom of the stack is at a fixed address.– Consists of logical stack frames that are pushed

when calling a function and popped when returning.

– Frame pointer (FP) points to a fixed location within a frame.

Page 6: Buffer Overflow

• Let’s see an example

• After gcc –S –o example1.s example1.c

• Call function is translated topushl $3

pushl $2

pushl $1

call function

Example1.c

example.s

Page 7: Buffer Overflow

– Its pushes the 3 arguments backwards into the stack.

– The instruction ‘call’ will push the IP onto the stack.

• Procedure prologpushl %ebp

movl %esp, %ebp

subl $20, %esp

Page 8: Buffer Overflow

• pushes the FP onto the stack.

• Copies the current SP onto EBP, make it the new FP.

• Allocates space for the local variables by subtracting their size from SP.– Memory can only be addressed in multiples of

the word size.– 5 byte buffer take 8 bytes (2 words).– 10 byte buffer take 12 bytes (3 words).– SP is subtracted by 20

Page 9: Buffer Overflow

c

b

a

ret

sfp

buffer1

buffer2

Stack

Page 10: Buffer Overflow

Buffer OverflowsBuffer Overflows

• Result of stuffing more data into a buffer than it can handle.

• See the following example:

• It copies a string without bounds checking by using strcpy() instead of strncpy().– Copy the contents of *str into buffer[] until a

null character is found.

example2.c

Page 11: Buffer Overflow

*str

ret

sfp

buffer

Stack

– Buffer[] (16 bytes) is much smaller than *str (256 bytes).

– All 250 bytes after buffer in the stack are being overwritten with character ‘A’ (0x41)

• Include SFP, RET and even *str.

• The return address becomes 0x41414141.

• That’s why you get segmentation error when the function returns.

Page 12: Buffer Overflow

What is the trick?What is the trick?

• Buffer overflow allows us to change the return address of a function.

– Add 12 to buffer[]’s address (return address).– Skip pass the assignment to the printf call.

example3.c

Page 13: Buffer Overflow

• By using a similar technique, a hacker can change the return address, so that the flow control will pass to his code.

• The code will be run under the username of the owner of the program.

• Usually a shell will be run.

• Read the article by Aleph One, to see how the shell code is obtained.

• Here is an example to test the shell code.

testsc2.c

Page 14: Buffer Overflow

Writing an ExploitWriting an Exploit

• Suppose we want to “overflow” this program.

• Create a program to put the overflow string in an environment variable.

• The program takes as parameters a buffer size and an offset from its own stack.– Guess the position of the buffer we want to

overflow.

vulnerable.c

exploit2.c

Page 15: Buffer Overflow

• The problem is we need to guess the exactly where the address of our code will start.

• A way to increase our chances– Pad the front of our overflow buffer with

NOP instructions.– Fill half of the buffer with NOP.– Place the code in the middle.– Then follow it with the return addresses.

Page 16: Buffer Overflow

– If the return address points anywhere in the string of NOPs, they will just get executed until they reach our code.

– Further improvement.• Put the code in another place.

• The environment variable contains pointer to another environment variable that contains the code.

• The environment variables are stored on the stack when the program is started.

exploit3.c

exploit4.c

Page 17: Buffer Overflow

• If vulnerable is owned by root, we can access the root account.

• Trial[mhwong]$ ./exploit4 768

using address: 0xbffff9d8

[mhwong]$ ./vulnerable $RET

bash# whoami

root

bash#

Hacker: “Ha! Ha! Ha! …I am the root now!!”

Page 18: Buffer Overflow

Advanced Buffer Overflow Advanced Buffer Overflow TechniquesTechniques

• Pass through filtering– Programs may filter some characters or

converts characters into other characters.– It is much more difficult to write an exploit

program, as the normal shell code cannot pass through the filter.

– For example, program may convert small letters into capital letters.

Page 19: Buffer Overflow

– Solution• Modify the shell code so that it doesn’t contain

small letters.– E.g. \x2f\x62\x69\x6e\x2f\x73\x68 ( /bin/sh) is converted

to \x2f\x12\x19\x1e\x2f\x23\x18

• Change the characters back when the shellcode is executed.

– Add \0x50 to \x62, \x69, \x6e, and \x68.

Page 20: Buffer Overflow

• Change uid– As programs run with root permission are

dangerous, some programs may• Call seteuid(getuid()) at start.

• Calls seteuid(0) when needed.

#include<string.h>#include<unistd.h>

int main(int argc,char **argv){ char buffer[1024]; seteuid(getuid()); if(argc>1) strcpy(buffer,argv[1]);}

Page 21: Buffer Overflow

– One may think that “strcpy(buffer,argv[1])” is OK, as the hacker can only get his own shell.

– In fact, the hacker can insert a code which calls setuid(0) in the shellcode to get the root shell.

setuid(0); code----------------------------------------------------------------------------char code[]= "\x31\xc0" /* xorl %eax,%eax */ "\x31\xdb" /* xorl %ebx,%ebx */ "\xb0\x17" /* movb $0x17,%al */ "\xcd\x80"; /* int $0x80 */----------------------------------------------------------------------------

Page 22: Buffer Overflow

• Break chroot– If the vulnerable program is chrooted, you can

access only chrooted directory.

#include<string.h>#include<unistd.h>

int main(int argc,char **argv){ char buffer[1024]; chroot("/home/ftp"); chdir("/"); if(argc>1) strcpy(buffer,argv[1]);}

Page 23: Buffer Overflow

– If you can execute the code below, you can break chroot.

– Compile and disassemble the above program and then get the shellcode.

main(){ mkdir("sh",0755); chroot("sh"); /* many "../" */ chroot("../../../../../../../../../../../../../../../../");}

Page 24: Buffer Overflow

• Open socket– Overflow the buffer in daemon.– Create a shellcode that do the following steps.

• Execute a shell

• Open a socket

• Connect your standard I/O

Page 25: Buffer Overflow

Techniques of Avoiding Buffer Techniques of Avoiding Buffer OverflowOverflow

• Modern Programming Languages– Most modern programming languages are

essentially immune to this problem.• Automatically resize arrays. E.g. Perl, Java

• Detect and prevent buffer overflows.E.g. Ada95, Java

– C language provides no protection against such problems.

– C++ can be easily used in ways to cause this problem.

Page 26: Buffer Overflow

• Careful Use of C/C++ Library Functions– avoid using functions that do not check bounds,

unless the bounds will never get exceeded.– Avoid strcpy(3), strcat(3), sprintf(3) and

gets(3).– These functions can be replaced with

strncpy(3), strncat(3), snprintf(3) and fgets(3).– Strlen(3) should be avoided unless you can

guarantee that there will be a terminating NUL character.

Page 27: Buffer Overflow

• Static and dynamically allocated buffer– Fix length buffer may be exploitable.

• Attacker sets up a really long string.

• When the string is truncated, the final result will be what the attacker wanted.

• Dynamically (re-)allocate all strings instead of using fixed-size buffers is recommended.

• Must be prepared for dynamic allocation to fail.

• Designed to be fail-safe when memory is exhausted.

Page 28: Buffer Overflow

• Use newer libraries.– Newer libraries for C include the strlcpy(3) and

strlcat(3).• Take full size of the destination buffer as a

parameter.

• Guarantee to NUL-terminate the result.

• Strlcpy copies up to size-1 characters from the NUL-terminated string src to dst and NUL-terminates the result.

• The strlcat function appends the NUL-terminated string src to the end of dst. It will append at most size-strlen(dst) –1 bytes, and NUL-terminates the results.

Page 29: Buffer Overflow

• Compilation solutions in C/C++– Newer compilers perform bounds-checking.– But it is not wise to depend on this technique as

your sole defense.• Only provide partial defense against buffer

overflows.

• Non-executable user stack area– It is possible to modify the kernel of any OS so

that the stack segment is not executable.– However, attackers can simply force the system

to call other “interesting” locations already in the program.

Page 30: Buffer Overflow

• Avoid installing set-user-id programs– Program is not running suid root.– User cannot achieve greater access levels.– However, you never know who is going to take

your program and set the suid bit on the binary.– It is also possible that users of your software

with no privileges at all. That means any successful buffer overflow attack will give them more privileges.

Page 31: Buffer Overflow

ReferenceReference

• Aleph One, “Smashing The Stack for Fun and Profit”, Phrack 49 Volume 7, Issue 49, File 14 of 16.

• Taeho Oh, “Advanced buffer overflow exploit”.