由于编程错误,我们得到分段错误。但是作为一个必要的工具,我们尝试了同样的事情,但是内核检测到它破坏了堆栈。内核究竟是如何看到差异的?
2 回答
简而言之,没有。分段错误是指内核能够检测到无效的内存访问,然后终止进程。内核无法检测到一些无效的内存访问,堆栈溢出就是建立在这些之上的。但是,编译器可以检测到堆栈溢出,并且在最新版本的 gcc (4.1+) 中,它具有针对堆栈粉碎攻击的内置保护。基本上,“金丝雀”值被放置在堆栈帧之间的堆栈上。检查以确保金丝雀仍然具有正确的值;如果没有(因为它被覆盖并且覆盖者无法猜测正确的值),则执行堆栈粉碎保护例程。有关详细信息,请参阅: http://en.wikipedia.org/wiki/Buffer_overflow_protection#GCC_Stack-Smashing_Protector_.28ProPolice。http://wiki.osdev.org/GCC_Stack_Smashing_Protector
您可以使用“-fno-stack-protector”禁用 gcc 保护,有关此内容的更多信息,请参阅:堆栈粉碎代码在 Linux 内核 2.6.38.7 上不起作用...请帮助
相反,分段错误只是发生在程序任何地方的无效内存访问,这意味着内核检测到对不在程序允许的内存区域中的内存的访问。AFAIK 这是使用 x86 段和虚拟内存的组合来检查的。内核/操作系统没有真正的方法可以知道访问是在原始程序代码中还是代码被某种方式利用;无论哪种方式,程序都试图访问它无法访问的内存,因此它被强制终止。
Segmentation fault 和砸栈不一样吗?
不,分段错误是指操作系统检测到无效的内存访问并终止您的进程。粉碎堆栈是指覆盖(返回)堆栈上的地址的行为,通常是通过溢出本地声明的数组。
当您破坏堆栈(作为攻击者)时,您的目标是让进程执行您选择的代码。您希望避免分段错误,因为它们会终止您尝试接管的进程。
由于编程错误,我们得到分段错误。
好吧,一些错误会导致分段错误,是的。其他错误什么都不做或只是导致错误结果(例如当攻击者成功利用缓冲区溢出并使程序运行完全不同的代码时)。
但是作为一个必要的工具,我们尝试了同样的事情,但是内核检测到它破坏了堆栈。
我不知道你刚才说了什么,但内核没有检测到“粉碎堆栈”。
内核究竟是如何看到差异的?
有什么区别?