我在网站上发现了一些相关帖子,但没有人解释我的问题。 代码在这里描述: Link
我的问题如下:
作者试图在notesearch.c程序中重写strcpy()函数的返回地址,缓冲区中有一个,以便shellcode(我理解的是在内存中植入机器代码)将被执行。
为此,他创建了一个缓冲区,看起来像:nop nop nop ... | shell代码.. |返回地址
根据我在调用strcpy()函数后的理解,缓冲区被放在堆栈上并将返回值覆盖到notesearch.c的main。他这样做,所以当strcpy()完成运行并想要返回main时,他将从缓冲区调用返回值。
我不明白的是:
在我看来,注入的返回地址始终与原始地址完全对齐。怎么会这样?
在书中说,注入的返回地址指向同一缓冲区中的shellcode。为什么我们要将shellcode放在同一缓冲区而不是内存的另一部分?这不能导致无限循环吗?
为什么我们不能将返回地址设置为缓冲区中shellcode的地址?或者对于那个问题的变量shellcode? p>
有人可以详细说明如何计算退货地址以及我们为何需要抵销?
答案 0 :(得分:0)
为什么我们要将shellcode放在同一个缓冲区而不是内存的另一部分?
只要您可以在该内存区域执行指令,您实际上可以随意将shellcode放在任何位置。话虽这么说,这个例子演示了一个基于堆栈的缓冲区溢出,在这样的漏洞中,很容易发现当前堆栈帧内局部变量的偏移量。
这不能导致无限循环吗?
假设shellcode不包含这样的无限循环 - 没有。然而,由于您正在修改执行流程,因此可能会产生错误。这实际上取决于shellcode。例如,大多数shellcode用于生成shell - 让我们假设使用了exec函数系列 - 所以一旦shell生成,原始的可执行映像将被shell覆盖。
为什么我们不能将返回地址设置为缓冲区上的shellcode的地址?
您可以,这只需要更精确的计算。使用NOP sled,您可以使用多个命中符号来执行shellcode。
有人可以详细说明如何计算退货地址吗?
作者获取了第一个声明的局部变量的地址,并计算了易受影响的缓冲区的位移。这里的第一个缺点是第一个声明的变量( i )可能不是编译后的第一个局部变量。如果要确保此类约束,则解决方法是使用结构(请参阅:Order of local variable allocation on the stack)。
作者可能多次运行该程序并调整偏移量,直到shellcode被触发。请记住,计算缓冲区的确切地址实际上是依赖于平台和编译器的。您必须调试程序并检查编译器如何详细说明堆栈帧等。
为什么我们需要抵消?
由于堆栈框架布局,需要“有效”偏移量来查找将击中NOP底座的地址。