携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
缓冲区溢出攻击
什么是缓冲区溢出
缓冲区是内存存储区域,在将数据从一个位置传输到另一个位置时临时保存数据。当数据量超过内存缓冲区的存储容量时,会发生缓冲区溢出(或缓冲区溢出)。因此,尝试将数据写入缓冲区的程序将覆盖相邻的内存位置。
例如,登录凭据的缓冲区可能设计为期望用户名和密码输入 8 个字节,因此,如果事务涉及 10 个字节的输入(即比预期多 2 个字节),则程序可能会写入超过缓冲区边界的多余数据。
缓冲区溢出会影响所有类型的软件。它们通常是由于格式不正确的输入或无法为缓冲区分配足够的空间造成的。如果事务覆盖了可执行代码,则可能导致程序行为不可预测,并生成不正确的结果、内存访问错误或崩溃。
缓冲区溢出示例
什么是缓冲区溢出攻击
攻击者通过覆盖应用程序的内存来利用缓冲区溢出问题。这会更改程序的执行路径,从而触发损坏文件或暴露私人信息的响应。例如,攻击者可能会引入额外的代码,向应用程序发送新指令以获取对 IT 系统的访问权限。
如果攻击者知道程序的内存布局,他们可以有意提供缓冲区无法存储的输入,并覆盖保存可执行代码的区域,用自己的代码替换它。例如,攻击者可以覆盖指针(指向内存中另一个区域的对象)并将其指向漏洞利用有效负载,以获得对程序的控制。
缓冲区溢出攻击的类型
基于堆栈的缓冲区溢出更常见,它利用仅在函数执行期间存在的堆栈内存。
基于堆的攻击更难执行,并且涉及淹没为程序分配的内存空间,超出用于当前运行时操作的内存。
哪些编程语言更容易受到攻击?
C 和 C++ 是两种极易受到缓冲区溢出攻击的语言,因为它们没有针对覆盖或访问内存中数据的内置保护措施。Mac OSX,Windows和Linux都使用用C和C++编写的代码。
PERL、Java、JavaScript 和 C# 等语言使用内置的安全机制,可最大程度地降低缓冲区溢出的可能性。
如何防止缓冲区溢出
开发人员可以通过代码中的安全措施或使用提供内置保护的语言来防止缓冲区溢出漏洞。
此外,现代操作系统还具有运行时保护。三种常见的保护措施是:
- 地址空间随机化 (ASLR) - 在数据区域的地址空间位置周围随机移动。通常,缓冲区溢出攻击需要知道可执行代码的位置,而随机化地址空间使得这几乎是不可能的。
- 数据执行保护 - 将某些内存区域标记为不可执行或可执行,从而阻止攻击在不可执行区域中运行代码。
- 结构化异常处理程序覆盖保护 (SEHOP) - 帮助阻止恶意代码攻击结构化异常处理 (SEH),这是一种用于管理硬件和软件异常的内置系统。因此,它可以防止攻击者能够利用 SEH 覆盖利用技术。在功能级别,SEH 覆盖是使用基于堆栈的缓冲区溢出来覆盖存储在线程堆栈上的异常注册记录来实现的。
代码和操作系统保护中的安全措施是不够的。当组织发现缓冲区溢出漏洞时,它必须快速做出反应以修补受影响的软件,并确保该软件的用户可以访问该修补程序。