在信息安全和编程中,缓冲区溢出或缓冲区溢出是一种异常,其中程序在将数据写入缓冲区时会超出缓冲区的边界并覆盖相邻的存储器位置。
介绍
缓冲区是专门用于存放数据的内存区域,通常在将程序从一个程序段移动到另一个程序段时,或者在程序之间移动。缓冲区溢出通常可能由格式错误的输入触发;如果假设所有输入都小于某个大小并且缓冲区被创建为该大小,那么产生更多数据的异常事务可能导致它写入缓冲区的末尾。如果这会覆盖相邻的数据或可执行代码,则可能导致程序行为不稳定,包括内存访问错误,错误结果和崩溃。
利用缓冲区溢出的行为是众所周知的安全漏洞。在许多系统中,程序的内存布局或整个系统都是明确定义的。通过发送旨在引起缓冲区溢出的数据,可以写入已知可保存可执行代码的区域并将其替换为恶意代码,或者有选择地覆盖与程序状态有关的数据,从而导致未被原始程序员。缓冲区在操作系统(OS)代码中很常见,因此可以进行执行权限提升的攻击并获得对计算机资源的无限制访问。 1988年着名的莫里斯蠕虫将其作为攻击技术之一。
通常与缓冲区溢出相关的编程语言包括C和C ++,它们不提供内置保护以防止访问或覆盖内存的任何部分中的数据,也不会自动检查写入数组的数据(内置缓冲区类型)是否在该数组的边界。边界检查可以防止缓冲区溢出,但需要额外的代码和处理时间。现代操作系统使用各种技术来对抗恶意缓冲区溢出,特别是通过随机化内存布局,或故意在缓冲区之间留出空间并寻找写入这些区域(“金丝雀”)的动作。
历史
早在1972年,计算机安全技术规划研究就提出了这样一项技术:“执行此功能的代码不会正确检查源地址和目标地址,允许部分监视器覆盖,因此缓冲区溢出被理解并部分公开记录。用户。这可以用来将代码注入监视器,允许用户控制机器。“ 。显示器将被称为内核。
最早记录的对缓冲区溢出的恶意攻击是在1988年。它是Morris蠕虫在互联网上传播自身的几个漏洞之一。该程序被利用是Unix上的一项名为finger的服务。后来,在1995年,Thomas Lopatic独立地重新发现了缓冲区溢出,并在Bugtraq安全邮件列表上公布了他的发现。一年后,1996年,Elias Levy(也称为Aleph One)在Phrack杂志上发表了题为“Smashing the Stack for Fun and Profit”的文章,逐步介绍了利用基于堆栈的
缓冲区溢出漏洞。
从那时起,至少有两个主要的互联网蠕虫利用缓冲区溢出来破坏大量系统。 2001年,Code Red蠕虫在微软的Internet信息服务(IIS)5.0 中利用了缓冲区溢出,2003年,SQL Slammer蠕虫病毒破坏了运行Microsoft SQL Server 2000的机器。
2003年,许可的Xbox游戏中出现的缓冲区溢出已被利用,允许未经许可的软件(包括自制游戏)在控制台上运行而无需进行硬件修改,称为modchips。PS2 Independence Exploit也使用缓冲区溢出来实现PlayStation 2的相同功能。使用“塞尔达传说:暮光公主”中的缓冲区溢出,Twilight黑客在Wii上实现了相同的功能。
技术说明
由于边界检查不足,写入缓冲区的数据也会破坏与目标缓冲区相邻的内存地址中的数据值时发生缓冲区溢出。 将数据从一个缓冲区复制到另一个缓冲区而不先检查数据是否适合目标缓冲区时,可能会发生这种情况。
例子:有关基于堆栈的溢出的更多信息:堆栈缓冲区溢出。在下面用C表示的例子中,程序有两个在内存中相邻的变量:一个8字节长的字符串缓冲区A和一个两字节的大端字节B。
最初,A只包含零字节,而B包含数字1979。
程序试图在A缓冲区中存储ASCII编码的空字符结尾字符串“excess”。
“过多”长度为9个字符,编码为10个字节,包括空终止符,但A只能占用8个字节。 如果没有检查字符串的长度,它也会覆盖B的值:
B的值已被无意中替换为由部分字符串形成的数字。 在这个例子中,“e”后跟一个零字节将变成25856.在分配的内存末尾写入数据有时可以被操作系统检测到,以产生终止该过程的分段错误错误。
为了防止在此示例中发生缓冲区溢出,可以使用strncpy替换对strcpy的调用,strncpy将A的最大容量作为附加参数,并确保将不超过此数量的数据写入A:
虽然此次阻止了缓冲区溢出,但如果源字符串的长度大于或等于缓冲区的大小(传递给函数的第三个参数),则strncpy库函数不会终止目标缓冲区,因此A 在这种情况下,它不是空终止的,不能被视为有效的C风格的字符串。
保护对策
1.编程语言的选择;
2.使用安全的库;
3.缓冲区溢出保护;
4.指针保护;
5.可执行空间保护;
6.地址空间布局随机化;
7.深度包检查;
8.测试.