2.3.3 缓冲区溢出

2025-06-17 22:27:45 更新

(一)定义

缓冲区溢出是一种非常普遍和危险的漏洞,在各种操作系统、应用软件中广泛存在。通过向程序的缓冲区写入超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃、系统关机或使程序执行其它指令,以达到攻击的目的。

(二)原理

缓冲区为可读写的内存区域;代码和数据都以二进制形式在此运行,缓存溢出攻击的目的,就是在缓冲区执行恶意代码。

(三)分类

  1. 栈溢出:在栈上分配的内存超过了栈的大小,就会发生栈溢出。栈是一种后进先出(LIFO)的数据结构,用于存储程序执行过程中的临时变量。当栈溢出时,程序会立即停止执行,并显示栈溢出错误信息。栈溢出攻击是最常见的缓冲区溢出攻击类型,发生栈溢出的基本前提是程序必须向栈上写入数据且写入的数据大小没有被控制。
  2. 堆溢出:指程序在动态分配内存时,分配的内存超出了堆的大小。堆是一种先进先出(FIFO)的数据结构,用于存储程序运行时长期需要的数据。当堆溢出时,程序可能不会立即停止执行,但会导致程序不稳定,甚至崩溃。在恶意攻击中,攻击者可能会利用堆缓冲区溢出来执行任意代码或获取敏感信息。
  3. 格式字符串溢出:指在编程语言中,涉及使用格式化字符串函数来打印字符串时,如果格式串由用户定制,攻击者就可以任意伪造格式串,利用 *printf() 系列函数的特性窥探堆栈空间的内容,超长输入可以引发传统缓冲区溢出,或是用“%n”覆盖指针、返回地址等。
  4. 整数溢出:整数类型都有一个取值范围,两个整数进行运算时,若结果大于最大值(上溢)或小于最小值(下溢),就是溢出。例如,最大值为a,在最大值与最小值之间发生以下计算:a+1=0或0-1=a,此时会发生溢出,其中a+1=0会发生上溢,0-1=a会发生下溢。利用整数的范围和符号等问题触发安全漏洞,大多数整形溢出不能直接利用,但如果该整形变量决定内存分配等操作,作为漏洞被间接利用。
  5. Unicode溢出:通过将Unicode字符插入需要ASCII字符的输入中来创建缓冲区溢出。ASCII和Unicode是使计算机表达文本的编码标准。由于unicode中有更多可用字符,所以许多unicode字符大于最大的ASCII字符。当出现Unicode溢出,可改变程序的工作方式,出现进一步的安全问题。