9

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

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

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

->shellcode_address in ?? ()

接着

Cannot find bound of current function

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

此外,当我执行它时,我遇到了分段错误,我已经用-g -fno-stack-protector. 为什么?

4

5 回答 5

8

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

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

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

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

通常,调试器仍然可以执行基本功能:它可以显示程序中的寄存器和内存,它仍然可以单步执行和设置断点,等等。它在做需要更复杂解释的事情时会遇到麻烦:它无法确定堆栈帧在哪里,它无法通过名称找到局部变量,等等。

于 2014-02-06T18:58:38.347 回答
3

很可能您在函数的某处(或类似的地方)有缓冲区溢出问题。它用不相关的数据覆盖函数的当前堆栈帧,并破坏进程中的返回地址,该地址通常存储在那里。结果是代码“返回”到某个不可预测的位置,并且无法确定它返回到的位置。这就是导致错误消息的原因。

于 2012-04-27T11:28:06.387 回答
1

你在栈上执行代码,然后问 GDB 你在哪个函数中。
显然,GDB 很困惑,因为你不在任何函数中。所以它显示了地址和“??”

您必须使用 -no-stack-protector 进行编译,因为 stack-protector 可以保护您免受您正在尝试做的事情的影响。
我不是说没有办法绕过它,但它需要更多的努力和对它的保护机制的充分理解。

于 2012-01-05T16:07:37.507 回答
1

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

于 2020-11-10T20:30:33.620 回答
0

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

于 2012-01-05T15:19:53.827 回答