当程序向缓冲区中写入数据的程序使该缓冲区的容量过载时,就会发生缓冲区溢出。这就像将 12 盎司的牛奶倒入 8 盎司的杯子中。
阅读本文后,您将能够:
复制文章链接
缓冲区溢出是一种异常现象,当软件向缓冲区中写入数据使缓冲区容量溢出时,会导致相邻存储器位置被覆盖。换句话说,过量的信息被传递到没有足够空间的容器中,而这些信息最终会替换相邻容器中的数据。
攻击者可以利用缓冲区溢出修改计算机的内存,以破坏或控制程序的执行。
缓冲区或数据缓冲区是一个物理内存存储区,用于在将数据从一个位置移到另一位置时临时存储数据。这些缓冲区通常位于 RAM 内存中。计算机经常使用缓冲区来帮助提高性能。大多数现代硬盘驱动器都利用缓冲的优势来有效地访问数据,并且许多在线服务也使用缓冲区。例如,在线视频传送服务经常使用缓冲区以防止中断。流式传输视频时,视频播放器一次下载并存储 20% 的视频到缓冲区,然后从该缓冲区进行流式传输。这样,连接速度的小幅下降或快速的服务中断都不会影响视频流性能。
缓冲区旨在容纳特定数量的数据。除非利用缓冲区的程序具有内置指令以在将太多数据发送到缓冲区时丢弃数据,否则程序将覆盖缓冲区附近的内存中的数据。
攻击者可以利用缓冲区溢出来破坏软件。尽管这个隐患得到了很好的理解,但缓冲区溢出攻击仍然是困扰网络安全团队的主要安全问题。2014 年,由于 SSL 软件中的缓冲区溢出漏洞,一种被称为“心脏出血”的威胁使亿万用户受到攻击。
攻击者可以故意将精心制作的输入馈入程序,程序将尝试将该输入存储在不够大的缓冲区中,因此输入会覆盖连接到缓冲区空间的部分内存。如果程序的内存布局定义明确,则攻击者可以故意覆盖已知包含可执行代码的区域。然后,攻击者可以用自己的可执行代码替换这些代码,这可以大大改变程序的工作方式。
例如,如果内存中的被覆盖部分包含一个指针(指向内存中另一个位置的对象),则攻击者的代码可以用另一个指向漏洞利用有效载荷的指针来替换该代码。这样就可以将整个程序的控制权转移给攻击者的代码。
某些编程语言比其他编程语言更容易发生缓冲区溢出。C 和 C++ 是两种脆弱性较高的热门语言,因为它们不包含内置的保护措施以防止访问或覆盖内存中的数据。Windows、Mac OSX 和 Linux 都包含用这两种语言编写的代码。
Java、PERL 和 C# 等更现代的语言具有内置特性,可帮助减少缓冲区溢出的机会,但不能完全阻止缓冲区溢出。
幸运的是,现代操作系统具有运行时保护,可帮助防护缓冲区溢出攻击。我们来探讨有助于防护漏洞利用风险的 2 种常见保护措施:
软件开发人员还可以通过使用内置保护的语言编写或在其代码中使用特殊的安全性程序,来预防缓冲区溢出漏洞。
尽管存在上述预防措施,但开发人员仍然发现了新的缓冲区溢出漏洞,有时是在遭遇成功的漏洞利用之后。发现新漏洞时,工程师需要修补受影响的软件,并确保该软件的用户可以获取补丁。
缓冲区溢出攻击有很多类型,它们采用不同的策略并针对不同的代码段。以下是一些最著名的类型。
*计算机依赖于两种不同的内存分配模型,称为堆栈和堆;两者都位于计算机的 RAM 中。堆栈结构整齐,并以“后进先出”的模型保存数据。最后放入堆栈中的任何数据都将首先发出,就像是插入弹夹中的最后一颗子弹将被首先发射一样。堆则是杂乱无章的额外内存池,数据不会以任何特定顺序进入或离开堆。由于从堆栈访问内存比从堆访问快得多,因此通常将堆保留为供较大的数据段或程序员想要显式管理的数据使用。