[EXPLOIT] 缓冲区溢出攻击原理与利用
┌─────────────────────────────────────────────────────────────┐
│ ███████╗██╗ ██╗██████╗ ██╗ ██████╗ ██╗████████╗ │
│ ██╔════╝╚██╗██╔╝██╔══██╗██║ ██╔═══██╗██║╚══██╔══╝ │
│ █████╗ ╚███╔╝ ██████╔╝██║ ██║ ██║██║ ██║ │
│ ██╔══╝ ██╔██╗ ██╔═══╝ ██║ ██║ ██║██║ ██║ │
│ ███████╗██╔╝ ██╗██║ ███████╗╚██████╔╝██║ ██║ │
│ ╚══════╝╚═╝ ╚═╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ │
└─────────────────────────────────────────────────────────────┘
1. 内存布局回顾
高地址
┌──────────┐
│ argc │
│ argv │
├──────────┤
│ envp │
├──────────┤ ← 环境变量
│ │
│ Stack │ ← 栈向下增长
│ ↓ │
│ │
├──────────┤
│ ↑ │
│ Heap │ ← 堆向上增长
│ │
├──────────┤
│ BSS │ ← 未初始化数据
├──────────┤
│ Data │ ← 已初始化数据
├──────────┤
│ Text │ ← 代码段
└──────────┘
低地址
2. 栈帧结构
当一个函数被调用时,栈帧如下:
┌─────────────────┐
│ function args │ ← 函数参数
├─────────────────┤
│ return address │ ← EIP 保存地址
├─────────────────┤
│ saved EBP │ ← 旧的基址指针
├─────────────────┤
│ local vars │ ← 局部变量
│ buffer[64] │ ← 我们的目标缓冲区
└─────────────────┘
↓ 栈增长方向
3. 漏洞代码示例
#include <stdio.h>
#include <string.h>
void vulnerable(char *input) {
char buffer[64];
strcpy(buffer, input); // 没有边界检查!
printf("Buffer: %s\n", buffer);
}
int main(int argc, char *argv[]) {
if (argc < 2) return 1;
vulnerable(argv[1]);
return 0;
}
4. 溢出原理
正常输入 "AAAA" (4字节):
┌──────────┬──────────┬──────────┬──────────────┐
│ buffer │ saved │ return │ args │
│ [64] │ EBP │ addr │ │
├──────────┼──────────┼──────────┼──────────────┤
│ AAAA.... │ 0xbf... │ 0x0804.. │ argv[1] │
└──────────┴──────────┴──────────┴──────────────┘
恶意输入 (72字节 "A" + 新地址):
┌──────────┬──────────┬──────────┬──────────────┐
│ buffer │ saved │ return │ args │
│ [64] │ EBP │ addr │ │
├──────────┼──────────┼──────────┼──────────────┤
│ AAAA.... │ AAAAAAAA │ 0xSHELL │ OVERFLOW!! │
└──────────┴──────────┴──────────┴──────────────┘
↑
EIP 被劫持!
5. 防护机制
| 机制 | 缩写 | 原理 |
|---|---|---|
| Stack Canary | SSP | 栈帧中放置随机值,溢出时先破坏 |
| NX Bit | DEP | 栈不可执行 |
| ASLR | ASLR | 地址随机化 |
| PIE | PIE | 位置无关代码 |
| RELRO | RELRO | 重定位只读 |
6. 现代绕过思路
即使有上述防护,仍有攻击面:
- ROP (Return-Oriented Programming): 利用已有代码片段
- ret2libc: 跳转到 libc 中的函数
- info leak: 先泄露地址绕过 ASLR
- GOT overwrite: 覆盖全局偏移表
⚠️ 本文仅用于安全教育,请勿用于非法用途。
[SYS] 防御等级: ████████░░ 80%
[SYS] 攻击面: ████░░░░░░ 40%
[SYS] 结论: 纵深防御是王道