在Mac OS 10.6上执行简单的缓冲区溢出

时间:2010-06-11 21:28:34

标签: c macos buffer-overflow fortify-source

我正在尝试了解堆栈基础溢出并编写一个简单的代码来利用堆栈。但不知怎的,它根本不起作用,只在我的机器上显示Abort陷阱(mac os leopard)

我猜Mac os对待溢出的方式不同,它不允许我通过c代码覆盖内存。例如,

strcpy(buffer, input) // lets say char buffer[6] but input is 7 bytes 

在Linux机器上,此代码成功覆盖下一个堆栈,但在mac os(Abort trap)

上被阻止

任何人都知道如何在mac机器上执行简单的堆栈溢出?

4 个答案:

答案 0 :(得分:11)

@joveha's answer是正确的,对于GCC,你必须使用-fno-stack-protector进行编译以关闭缓冲区溢出保护。

但是,此外,您还需要禁用FORTIFY_SOURCE选项,否则如果尝试使用strcpy或{{1}之类的缓冲区溢出,您将获得“中止陷阱” }}

要禁用它,只需使用标记memcpy进行编译,例如:

-D_FORTIFY_SOURCE=0

来源:Turning off buffer overflow protections in GCC

答案 1 :(得分:6)

包括

int main(int argc, char **argv) {
    char buffer[4];
    puts("Hello");
    gets(buffer);
    return 0;)
}

并将其命名为:

printf "0123456789abcdefghij\260\037" | ./a.out

\ 260 \ 037是以八进制和小端顺序的main(0x1fb0)的地址。

在发生总线错误之前,您应该看到hello print两次。诀窍是使用调试器(甚至gdb会这样做)知道你想要结束的地方和返回地址。它与Linux中的不一样!

MacOS X for i386(i386的大多数操作系统实际上包括Linux和Windows),特别是< = Leopard不是最安全的操作系统。

编辑:刚刚意识到我使用clang作为编译器。因此,您需要将其调整为gcc,但我可以告诉您它的工作变化不大:p。

答案 2 :(得分:4)

堆栈溢出?

术语堆栈溢出是指堆栈大小试图超出当前平台和/或配置允许的最大限制时的情况。你要做的事情与堆栈溢出无关。如果你想看堆栈溢出,写一个无限递归函数,执行它,等待它溢出:

void foo() {
  foo();
}

(希望编译器不会将尾递归优化为循环。如果确实如此,请使其更复杂,非尾递归。)

您似乎要做的是重现臭名昭着的缓冲区溢出漏洞。虽然有问题的缓冲区应该在堆栈中分配,但漏洞从未被称为“堆栈溢出”。为了实际演示漏洞,仅仅超出某些缓冲区的边界是不够的。重点是在最初由存储的返回地址占用的堆栈区域中设置一个预定值,这样当函数完成时,它“返回”到其他一些(可能是恶意的)代码而不是原始的调用代码。

那么,你要做的是什么?堆栈溢出?还是缓冲区溢出?

答案 3 :(得分:3)

Mac OS上的编译器已编译成stack canary,它为您提供了中止陷阱。在编译器手册中搜索如何禁用它。

使用GCC,此选项为-fno-stack-protector

另外注意,溢出1个字节肯定不足以触发除编译器堆栈检查之外的任何内容。使用类似12个字节的东西:)