需要全面清晰的 NOP sled 技术解释

标签 c arrays security stack buffer-overflow

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

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

好吧,假设我们在函数 foo() 中有一个缓冲区 char a[8]; foo() 的堆栈帧如下所示(32 位):

enter image description here

现在,我们要做的是覆盖调用 foo() 时保存在堆栈中的“返回”值

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

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

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

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

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

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

最佳答案

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

We always know how far is the saved 'return' from our overflown buffer, don't we ? :/

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

Then if we have a large array of NOPs coming before the shellcode, we have a high chance of writing NOP (i.e. 0x90) value into location of 'return', hence overwriting the original value

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

关于需要全面清晰的 NOP sled 技术解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18043650/

相关文章:

c# - 安全异常 ASP.NET/MySQL

c - 为什么连续写入会在缓冲区中保留4K字节?

c# - 将 C 输出转换为 C# 输入

javascript - 从 JSON 数组获取数据并使用 React 中的循环根据数据设置状态

c - 这在 C 编程中会做什么 :++group[ (int) (value[i]+0. 5)/10]

security - 如何成为 SAML 服务提供商

c - fgets() 在多次执行后崩溃

c - 小行星式运动,行进方向与 vector 三角形的方向不一致

python - MATLAB 到 Python 转换数组

java - 处理ResourceServer中的spring security认证异常