I have been reviewing different styles of buffer overflows and ran into a problem I cannot remember why it occurs. The code as follows is the program I am attempt to perform a buffer overflow on:
#include <stdio.h>
void func(char *buff){
char buffer[5];
strcpy(buffer, buff);
printf("%s\n", buffer);
}
int main(int argc, char *argv[]){
func(argv[1]);
printf("I'm done!\n");
return 0;
}
The core concept of the program is very simple, I just overflow the buffer to overwrite the return address of func()
. That all works great when I give it an address such as 0x0804850c
which happens to be the <_fini>
of the program. The end result when I implement the overflow with that address is the program quits "gracefully" without printing I'm done!
. The problem I am running into now is when I attempt to redirect the return address to something say an environment variable located at 0xbfffd89
.
The shell code located in that particular environment variable should simply quit the program after saying hello
. However that does not occur, the program simply seg faults and that's it. The shell code has already been confirmed to work in the previous program I wrote to test out shell code. Anyone have any ideas why this is not working. Thx
Can you confirm the address of the variable between runs? If your system uses something like ASLR, it can be different every run. The address of the argv[1] may be, however, given via some register, so if you supply the return address with the address of instruction doing indirect call via this register (you will probably find such instruction using
objdump -d
on your program), it will run your code at whatever address it will be - assuming this address is in the executable page. And registers are used in your ABI to pass parameters. There can be another problems however...If you provide more details (possibly, insluding disassembly of the program), maybe it could be answered more specifically.
Modern linux distros are hardened against this sort of attack. The NX bit is set for stack pages on x86-64, for example. And mapping addresses are randomized to prevent the ability to guess from outside the process. See the following:
http://en.wikipedia.org/wiki/Executable_space_protection http://en.wikipedia.org/wiki/Address_space_layout_randomization
Basically, if you want to write an exploit for a modern system you're going to have to do some more work.
Environment variables are located in a region of memory that has read & write permission but not execute permission. I reproduced this easily as follows:
Running under
gdb
, I got this:I then looked up the address 0x00007fffffffeb51 if
/proc/PID/maps
and found a line like this:There's a
-
where thex
(execute) bit would normally be found.