4

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

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

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

在 Linux 机器上,此代码成功覆盖下一个堆栈,但在 mac os 上阻止(中止陷阱)

有人知道如何在 mac 机器上执行简单的基于堆栈的溢出吗?

4

4 回答 4

14

@joveha 的答案是正确的,对于 GCC,您必须使用 to 来编译-fno-stack-protector缓冲区溢出保护。

但是,您还需要禁用该FORTIFY_SOURCE选项,否则如果您尝试使用类似strcpymemcpy.

要禁用它,只需使用 flag 编译-D_FORTIFY_SOURCE=0,例如:

gcc -g -fno-stack-protector -D_FORTIFY_SOURCE=0 -o overflow overflow.c

来源:关闭 GCC 中的缓冲区溢出保护

于 2013-06-11T22:38:29.433 回答
5

包括

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 打印。诀窍是使用调试器(甚至 gdb 也会这样做)来了解您想要结束的位置以及返回地址在哪里。它不会和Linux一样!

适用于 i386 的 MacOS X(大多数适用于 i386 的操作系统实际上包括 Linux 和 Windows),尤其是 <=Leopard 并不是最安全的操作系统。

编辑:刚刚意识到我正在使用 clang 作为编译器。所以你需要让它适应gcc,但我可以告诉你它几乎不需要改变:p。

于 2010-06-11T23:31:01.970 回答
4

堆栈溢出?

术语堆栈溢出是指堆栈大小试图增长到超出当前平台和/或配置允许的最大限制的情况。您正在尝试做的事情与堆栈溢出完全无关。如果您想查看堆栈溢出,请编写一个无限递归函数,执行它并等待它溢出:

void foo() {
  foo();
}

(希望编译器不会将尾递归优化成一个循环。如果是这样,让它更复杂一点,非尾递归。)

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

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

于 2010-06-11T21:53:58.433 回答
3

您在 Mac OS 上的编译器已在堆栈金丝雀中编译,它会为您提供中止陷阱。在您的编译器手册中搜索如何禁用它。

对于 GCC,此选项为-fno-stack-protector.

另外需要注意的是,只有 1 个字节的溢出肯定不足以触发编译器堆栈检查之外的任何操作。使用类似 12 个字节的内容:)

于 2010-06-12T12:56:18.237 回答