软件中最常见和最古老的安全漏洞之一是缓冲区溢出漏洞。从操作系统到客户端/服务器应用程序和桌面软件的各种软件都会出现缓冲区溢出漏洞。这通常是由于编程错误以及应用程序端缺少或差的输入验证。在本文中,我们将了解缓冲区溢出的确切含义,它们如何工作以及它们如何成为严重的安全漏洞。我们还将研究缓冲区溢出发生时会发生什么,以及减少其有害影响的缓解技术。
什么是缓冲区溢出?
缓冲区溢出是一种运行程序试图在内存缓冲区外写入数据的情况,该内存缓冲区并不打算存储该数据。当发生这种情况时,我们讨论的是缓冲区溢出或缓冲区溢出情况。内存缓冲区是计算机内存(RAM)中用于临时存储数据的区域。这种缓冲区可以在所有程序中找到,用于存储输入,输出和处理的数据。
存储在缓冲区中的数据示例是登录凭据或FTP服务器的主机名。在处理之前临时存储的其他数据也可以存储在缓冲器中。从字面上看,这可以是用户输入字段(如用户名和密码字段)到用于导入某些配置文件的输入文件。当写入缓冲区的数据量超过预期的数据量时,内存缓冲区溢出。例如,当预期最大为8个字节的用户名并且给出10个字节的用户名并将其写入缓冲区时,就会发生这种情况。在这种情况下,缓冲区超过2个字节,并且在未阻止发生时会发生溢出。这通常是由于糟糕的编程和缺乏输入清理造成的。
将10个字节的数据(用户名12)写入8字节缓冲区时缓冲区溢出的示例。
发生缓冲区溢出时会发生什么?
当发生内存缓冲区溢出并将数据写入缓冲区外时,正在运行的程序可能会变得不稳定,崩溃或返回损坏的信息。内存的覆盖部分可能包含正在运行的应用程序的其他重要数据,这些数据现在被覆盖并且不再可用于程序。缓冲区溢出甚至可以运行其他(恶意)程序或命令,并导致任意代码执行。
任意代码执行和权限提升
当使用缓冲区溢出漏洞在内存中写入恶意数据并且攻击者能够控制程序的执行流程时,我们正在处理严重的安全漏洞。缓冲区溢出可能会成为严重的安全问题。黑客可以利用这些安全问题来对主机进行(远程)控制,执行权限提升或由于任意代码执行而导致的更多错误。任意代码执行是在缓冲区中注入代码并使其执行的过程。
通过利用缓冲区溢出漏洞在执行系统特权的程序中执行任意代码来执行权限提升。执行的代码可以是shellcode,例如,为攻击者提供具有管理权限的OS shell,甚至可以向系统添加新的(管理员)用户。此外,在缓冲区溢出时,执行的代码发生在正在运行的应用程序的上下文中。这意味着当被利用的应用程序在具有管理权限的情况下运行时,恶意代码也将以管理权限执行。
拒绝服务(DoS)
并非所有缓冲区溢出漏洞都可以被利用来获得任意代码执行。此外(远程)拒绝服务攻击只能在运行程序崩溃时执行。由于缓冲区溢出漏洞可能发生在任何软件中,DoS攻击不仅限于服务和计算机。此外,还可以定位路由器,防火墙物联网设备以及运行操作系统的任何其他设备。这种情况的一个例子是最近的Cisco ASA IKEv1和IKEv2缓冲区溢出漏洞。其中一些远程攻击只会崩溃并强制重启防火墙,导致几分钟的停机时间。
如何防止缓冲区溢出?
可以通过多种方式防止或减轻软件中的缓冲区溢出。缓解是在威胁发生之前或之后最小化威胁影响的过程。这正是我们在缓冲区溢出时需要做的事情。可以防止它们在发生之前发生(主动)。但是,由于缓冲区溢出不断发生,尽管主动采取措施来避免它们,我们还需要一些机制来最小化它们发生时的影响(反应性对策)。让我们来看看缓冲区溢出防止和缓解是如何工作的。
防止缓冲区溢出
最好和最有效的解决方案是防止代码中发生缓冲区溢出情况。例如,当预期最多8个字节作为输入数据时,可以将任何时候写入缓冲区的数据量限制为8个字节。此外,程序员应该使用保存功能,测试代码并相应地修复错误。应尽可能使用这些缓冲区溢出防止的主动方法来限制缓冲区溢出漏洞。
缓冲区溢出缓解
另一种保护缓冲区溢出的方法是在它们发生时检测它们并缓解这种情况。这是一种被动的方法,专注于尽量减少有害影响。有效缓解的一个例子是现代操作系统,它保护某些存储区域不被写入或执行。这将防止攻击者在发生缓冲区溢出时将任意代码写入内存。DEP,ASLR,SEHOP以及可执行空间和指针保护等实现尽量减少缓冲区溢出的负面影响。这不会阻止缓冲区溢出,但它确实可以最大限度地减少影响。
被动缓冲区溢出检测的另一种方法是使用入侵检测系统(IDS)来分析网络流量。IDS能够检测已知利用缓冲区溢出漏洞的网络流量中的签名。IDS可以缓解攻击并防止有效负载在目标系统上执行。
缓冲区溢出如何在代码中工作?
让我们通过查看程序代码来了解缓冲区溢出是如何实际工作的。我们解释这个过程使用一个非常有名的函数,容易受到缓冲区溢出的影响,是c库中的strcopy()函数。此函数使用2个指针作为参数,指向要从中复制的源数组的源和指向要写入的字符数组的目标指针。执行该函数时,字符的源数组将被复制到目标数组,并且在执行此操作时不会检查边界。当源缓冲区大于目标缓冲区时,缓冲区溢出。
用strcpy()缓冲区溢出
下图是使用超出目标缓冲区的源的strcpy()函数的示例。
在您选择的IDE中,代码看起来如下图所示:
在这个例子中,缓冲区溢出了2个包含无害1和2的字节。由于strcpy()函数不执行边界检查,我们可以在缓冲区空间之外写入任何内容。还有像shellcode这样的恶意代码。在下面关于缓冲区溢出的教程中,我们将学习使用shellcode而不是1和2来覆盖缓冲区。我们还将学习如何控制程序的执行流程并在缓冲区外执行恶意shellcode。
得到知识
我们已经了解到缓冲区溢出是由正在运行的程序在内存缓冲区外写入数据的某些条件引起的。通过注入(shell)代码并将正在运行的程序的执行流重定向到该代码,攻击者能够执行该代码。这称为任意代码执行。通过任意代码执行,攻击者能够获得(远程)控制特定目标,提升特权或导致目标上的拒绝服务。
可以使用多种技术主动防止和缓解缓冲区溢出。程序员应该编写安全代码并测试它是否存在缓冲区溢出。当不阻止缓冲区溢出时,仍然可以使用诸如保护内存不被写入的反应方法来缓解它。
我们试图解释缓冲区溢出基础知识,而不是很多技术细节。在以下有关此主题的教程中,我们将了解有关基于堆栈的缓冲区溢出,基于堆的缓冲区溢出以及如何检测和利用软件中的缓冲区溢出漏洞的更多详细信息。我们还将学习shellcode并编写我们自己的基本缓冲区溢出漏洞。
版权声明
本文仅代表作者观点,不代表黑白网立场。 如文章侵犯了您的权利,请通过邮箱联系我们删除 E-Mail:server@heibai.org 黑白网官群:238921584