Vulnerability-wiki

缓冲区溢出漏洞(Buffer Overflow)

缓冲区溢出漏洞是由于程序在向内存中的缓冲区写入数据时,没有进行边界检查,导致数据写入超出预分配的内存范围,进而覆盖其他内存内容,甚至控制程序流程。

一、漏洞原理

缓冲区通常是在栈(stack)或堆(heap)中分配的内存区域,用于存储临时数据(如字符串、数组)。当用户输入的内容超出缓冲区的长度时,如果程序未对输入长度进行限制,攻击者就可能会:

这些都可能被用于实现任意代码执行、提权或拒绝服务攻击。

二、常见缓冲区溢出类型

类型 描述
栈溢出(Stack Overflow) 覆盖栈上的局部变量或返回地址
堆溢出(Heap Overflow) 覆盖堆上的数据结构(如函数指针)
全局区溢出 覆盖全局变量或程序指针
Unicode 溢出 在 Unicode 编码处理过程中引发的溢出
Off-by-one 溢出 由于边界判断错误,只溢出 1 个字节,仍可能控制程序执行流

三、漏洞利用方式

  1. 构造超长输入,覆盖返回地址或函数指针。
  2. 将恶意 shellcode 写入缓冲区中。
  3. 利用控制流劫持将程序跳转到 shellcode 执行。

四、防御手段

方法 说明
栈保护机制(Stack Canary) 在返回地址前插入随机数,用于检测栈被破坏
数据执行保护(DEP/NX) 阻止堆栈等区域执行代码
地址空间布局随机化(ASLR) 随机化内存地址,增加攻击复杂度
安全编程语言 使用如 Java、Python 等具有边界检查的语言
编译器检查 使用 -fstack-protector-Wall 等参数加强安全检查
静态/动态分析 利用工具检测溢出风险(如 Valgrind、ASAN)

五、利用示例(手工构造)

// vulnerable.c
#include <stdio.h>
#include <string.h>

void vulnerable() {
    char buffer[64];
    gets(buffer);  // 不安全函数,容易造成栈溢出
    printf("You entered: %s\n", buffer);
}

int main() {
    vulnerable();
    return 0;
}

攻击者可以构造超长字符串填满 buffer,并覆盖返回地址,指向自定义的 shellcode,从而执行任意代码。

六、真实案例:CVE-2017-1000112 - Git 命令注入导致缓冲区溢出

漏洞描述: Git 2.14.1 之前存在缓冲区溢出漏洞,当用户使用 git shell 并传入超长命令参数时,攻击者可构造恶意 SSH URL 触发栈溢出,导致远程命令执行。

ssh://[long string]@git-server/repo.git

利用条件:

修复方式:

参考链接:https://nvd.nist.gov/vuln/detail/CVE-2017-1000112