堆溢出的危险?

我有一个关于堆溢出的问题。

我知道如果一个堆栈变量超出它的缓冲区,它可能会覆盖EIP和ESP值,例如,让程序跳转到编码器不希望它跳转的地方。

据我所知,这看起来像是因为向后的小端存储(其中数组中的字符“向后”存储,从最后到第一个)。

另一方面,如果你把那个数组放入堆中,它会与堆栈一起增长,并且你会溢出它,它会将随机垃圾写入空的内存空间吗?
(除非你在solaris上的哪个地方,据我所知有一个大端系统,旁注)
这基本上是危险吗,因为它会写入“空白空间”?
所以没有目标跳转到代码不是为其设计的地址和区域?
我错了吗?

要指定我的问题:
我正在编写一个程序,其中用户通过命令行执行它时传递​​一个字符串参数和一个标志,我想知道用户是否可以使用此字符串参数执行hack,当它放在堆上时mallocfunction。

天哪,我希望这个问题不是新手:/请尽量解释简单

感谢您的回答,请在几个小时内见到您,晚安。

另一方面,如果你把那个数组放入堆中,它会与堆栈一起增长,并且你会溢出它,它会将随机垃圾写入空的内存空间吗?

你做了几个假设:

  1. 您假设堆位于主内存段的末尾。 这不一定是这样。

  2. 您假设堆中的对象位于堆的末尾。 这不一定是这样。 (事实上​​,它通常不是这样……)

这是一个无论堆如何实现都可能导致问题的示例:

char *a = malloc(100); char *b = malloc(100); char *c = malloc(100); for (int i = 0; i < 200; i++) { b[i] = 'Z'; } 

超出b结尾的写入可能会践踏堆中的ac ......或其他对象,或者自由列表。

根据您践踏的对象,您可能会覆盖函数指针,或者您可能会执行其他损坏,从而导致分段错误,不可预测的行为等。 这些东西可以用于代码注入,从而导致代码以其他方式从安全角度出现故障......或者只是通过崩溃目标应用程序/服务来实现拒绝服务攻击。

堆溢出有多种方式可以导致代码执行:

  • 最明显的 – 你溢出到另一个包含函数指针的对象,并覆盖其中一个。
  • 稍微不那么明显 – 你溢出的对象本身不包含函数指针,但它包含将用于写入的指针,你可以覆盖其中一个指向函数指针,以便后续的写入覆盖函数指针。
  • 利用堆簿记结构 – 通过覆盖堆分配器本身用于跟踪已分配/空闲块的大小和状态的数据,您可以欺骗它覆盖内存中其他地方有价值的东西。
  • 等等。

对于一些高级技术,请参阅:

http://packetstormsecurity.com/files/view/40638/MallocMaleficarum.txt

即使您无法覆盖返回地址,您如何看待攻击者修改其余数据? 这不应该激动你。

一般来说回答你的问题:让用户不检查其大小的情况下将数据复制到任何地方是一个非常糟糕的主意。 你绝对不应该这样做,尤其是故意的。

如果用户没有任何伤害,他们可能会通过覆盖有用数据或导致页面错误来使程序崩溃。 如果您的用户是恶意用户,您可能会让他们劫持您的系统。 两者都非常不受欢迎。

字节顺序对缓冲区溢出无关紧要。 大端机器和小端机器一样脆弱。 唯一的区别是恶意数据的字节顺序。

您可能正在考虑而不是堆栈增长的方向,这与字节顺序无关。 在它成长的情况下,您将无法劫持声明缓冲区的函数的返回地址。 但是,如果将该缓冲区地址传递给任何其他函数,并且此函数溢出,则攻击者可能会更改此函数的返回地址。 例如,如果您调用scanf memcpy或任何其他函数来修改缓冲区(假设编译器没有内联它们),就会出现这种情况。

堆栈通常向下增长。 在这种情况下,攻击者可以使用溢出来劫持声明它的函数的返回地址。

换句话说,堆栈配置和字节顺序都不能提供有效的堆栈缓冲区溢出保护。

至于堆:

另一方面,如果你把那个数组放入堆中,它会与堆栈一起增长,并且你会溢出它,它会将随机垃圾写入空的内存空间吗?

答案,几乎总是如此, 取决于 ,但可能不是 。 glibc中的malloc的32位实现将簿记结构保留在缓冲区的末尾(或至少用于)。 通过使用正确的咒语溢出到簿记结构上,当分配是free ,您可以在任意位置free地写入四个任意字节。 这是很大的力量。 这种漏洞经常在捕获旗帜比赛中出现,并且非常容易被利用。

小Endian格式化的方式并不是整个数组都是向后写的。

相反,每个可寻址位置(32位或64位宽,取决于架构)将以小端格式具有32位(或64位)的那些字节。

当(例如)30字节的分配(通过malloc)时,malloc返回的地址是该30字节的最低地址,并且最高地址(未返回)高29个字节。

注意:通常,对于许多体系结构,只能直接寻址32/64位区域的最低地址。

通过读取所有字节然后提取/更新所需的字节,在硬件中完成访问任何其他字节

malloc将返回一个位于’32bit边界’的地址

这意味着该地址中的低5位将为0