当我覆盖易受攻击程序的ret地址时,为什么我会“找不到当前函数的界限”?

时间:2012-01-05 11:11:07

标签: c stack buffer-overflow shellcode

我想利用基于堆栈的缓冲区溢出来进行教育。

使用main中的参数调用典型函数,该函数作为程序的输入提供给保存参数的本地缓冲区。给定nops+shellcode+address_shellcode的输入,我将利用它。

使用gdb调试后,我找到了shell代码的地址,因为它将作为参数传递,并且在strcpy之后我检查堆栈并且$ebp+8已成功返回地址用shell代码的地址覆盖。所以我有我想要的东西。但是当我向前推进执行时,我得到了:

->shellcode_address in ?? ()

然后

Cannot find bound of current function

返回地址具有我想要的值。有什么想法发生了什么?

当我执行它时,我遇到了分段错误,我用-g -fno-stack-protector编译了它。为什么呢?

5 个答案:

答案 0 :(得分:6)

调试器知道程序中函数代码的开始和结束位置,因为这些信息是在调试数据中提供的,或者是因为它使用可执行文件中可见的任何外部符号来提供基本信息。

当堆栈处于正确状态时,它包含调用函数的返回地址,并且在其上方的某个地方,返回更高级别调用函数的返回地址,依此类推。在执行各种调试器命令时,它使用这些返回地址(以及堆栈和进程状态中的其他信息)来显示这些函数的名称。这需要在调试器中查找返回地址,了解函数的位置。

一旦溢出缓冲区并破坏堆栈,就会破坏正确的返回地址。相反,您有一个不同的地址(如果您的漏洞有效,则指向您的shellcode)。当调试器试图找出该地址所在的函数时,它会失败,因为该地址不在程序的任何函数中。

发生此故障时,调试器会打印您看到的错误消息。

通常,调试器仍然可以执行基本功能:它可以显示程序中的寄存器和内存,它仍然可以单步执行并设置断点,等等。它将无法处理需要更复杂解释的事情:它无法确定堆栈帧的位置,它无法按名称查找局部变量,等等。

答案 1 :(得分:0)

假设您的Linux发行版是最新的,并且您使用的是x86ish体系结构,则无法再从用户空间内存执行shell代码(这也适用于其他体系结构,我只是不熟悉它们)。有很多原因,在您的情况下很可能是nx位的设置。转到Linux安全手册页,您将看到默认启用的大量安全措施;和谷歌“在2011年粉碎堆栈的乐趣”可能的方式围绕它。使用'-fno-stack-protector'进行编译只意味着不设置金丝雀值;但这还不够。如果你想为了教育目的而这样做,我建议安装一个像虚拟机这样的虚拟机,以及一个旧的发行版。

答案 2 :(得分:0)

您正在堆栈上执行代码,并询问GDB您所处的功能。
显然,GDB很困惑,因为你没有任何功能。所以它显示了地址和“??”

你必须使用-no-stack-protector进行编译,因为stack-protector可以保护你免受你想要做的事情。
我并不是说没有办法绕过它,但需要付出更多的努力并且很好地理解它的保护机制。

答案 3 :(得分:0)

很可能你在函数的某处有一个缓冲区溢出问题 (或类似的东西)。它会覆盖函数的当前堆栈帧 与不相关的数据,并破坏过程中的返回地址,这是 通常存储在那里。结果是代码“返回” 到一些不可预测的位置,无法弄清楚它返回的位置。 这是导致错误消息的原因。

答案 4 :(得分:0)

使用函数返回地址破坏了寄存器。现在返回地址是非法的,调试器无法访问它。查看消息。