需要全面而清晰的NOP雪橇技术解释

时间:2013-08-04 13:50:41

标签: c arrays security stack buffer-overflow

我已经浏览了很多网络,仍然无法理解它的工作方式

此链接也没有成功: How does a NOP sled work?

好的,假设我们在函数char a[8];中有一个缓冲区foo() 并且foo()的堆栈帧看起来像这样(32位):

enter image description here

现在,我们想要做的是覆盖'return'值,在调用foo()时保存在堆栈中

他们说问题是,我们无法预测保存的“返回”值的位置

但为什么呢?例如,如果函数foo()具有在所有其他局部变量之前定义的缓冲区,如上图所示,那么我们总是知道我们需要填充为缓冲区分配的8个字节,然后是4个字节的已保存的EBP然后我们得到了“回归” 或者,如果在缓冲区之前定义了其他局部变量,比如2个整数,那么我们考虑为缓冲区分配8个字节,然后考虑这2个本地整数的8个字节,然后是4个字节的已保存EBP,然后我们得到“返回”

我们总是知道从溢出的缓冲区中保存的“返回”有多远,不是吗? :/

如果我们不这样做,请解释。那是我的问题1。

我的问题2是,好吧,我们假设我们不知道'return'的值保存在哪里。然后,如果我们在shellcode之前有大量的NOP,我们很有可能将NOP(即0x90)值写入'return'的位置,从而覆盖原始值
现在,当函数foo()返回时,0x90的值被加载到EIP(指令指针)而不是恢复其正常流程,程序将从地址0x90执行,不是吗?
我想我在这里误解了一些东西

请不要关闭我的问题,即使有一个类似的问题,我在一开始就提供了链接, 我想这个问题会更全面,更清晰

1 个答案:

答案 0 :(得分:0)

首先我们假设没有地址空间随机化,堆栈是可执行的。

  

我们总是知道从溢出的缓冲区中保存的“返回”有多远,不是吗? :/

不,我们不知道。局部变量与保存的EBP和返回地址之间存在未指定数量的填充字节。这个字节数可能取决于编译器版本。

  

然后,如果我们在shellcode之前有大量的NOP,我们很有可能将NOP(即0x90)值写入'return'的位置,从而覆盖原始值

我们的想法是在返回地址后面包含所有NOP值。这样我们就可以用堆栈中shellcode的“近似”地址覆盖返回地址。确切的shellcode地址可能取决于操作系统版本,但也取决于程序参数以及环境变量的大小和数量,因为它们位于堆栈地址空间中。