缓冲区溢出漏洞是由于程序在向内存中的缓冲区写入数据时,没有进行边界检查,导致数据写入超出预分配的内存范围,进而覆盖其他内存内容,甚至控制程序流程。
缓冲区通常是在栈(stack)或堆(heap)中分配的内存区域,用于存储临时数据(如字符串、数组)。当用户输入的内容超出缓冲区的长度时,如果程序未对输入长度进行限制,攻击者就可能会:
这些都可能被用于实现任意代码执行、提权或拒绝服务攻击。
| 类型 | 描述 |
|---|---|
| 栈溢出(Stack Overflow) | 覆盖栈上的局部变量或返回地址 |
| 堆溢出(Heap Overflow) | 覆盖堆上的数据结构(如函数指针) |
| 全局区溢出 | 覆盖全局变量或程序指针 |
| Unicode 溢出 | 在 Unicode 编码处理过程中引发的溢出 |
| Off-by-one 溢出 | 由于边界判断错误,只溢出 1 个字节,仍可能控制程序执行流 |
| 方法 | 说明 |
|---|---|
| 栈保护机制(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,从而执行任意代码。
漏洞描述: Git 2.14.1 之前存在缓冲区溢出漏洞,当用户使用 git shell 并传入超长命令参数时,攻击者可构造恶意 SSH URL 触发栈溢出,导致远程命令执行。
ssh://[long string]@git-server/repo.git
利用条件:
修复方式: