1. 漏洞机理 (The Mechanism)

C 语言不进行数组边界检查。如果向栈上的局部数组(Buffer)写入超过其容量的数据:

  1. 覆盖局部变量: 破坏程序逻辑。
  2. 覆盖保存的 %rbp: 破坏上层栈帧。
  3. 覆盖返回地址 (Return Address): 致命一击
    • 当函数执行 ret 时,CPU 会跳转到攻击者写入的地址(如 Shellcode 或 ROP gadget)。

2. 攻击形式

  • Code Injection: 这里的“数据”包含可执行机器码(Shellcode)。跳转到栈上执行。
  • ROP (Return-Oriented Programming): 利用现有的代码片段(Gadgets)串联执行流。对抗 NX/DEP 的主要手段。

攻击原理:

地址 (高)    |      栈内存内容 (4字节/格)    |  说明 / 寄存器指向
  -----------+-------------------------------+-----------------------
  0xbffffc98 | [        ......           ] | 调用者(Caller)的栈内容
  0xbffffc94 | [  Old EBP (0xbffffcxx)   ] | <- 调用 getline 前的 %ebp
  0xbffffc90 | [      0x08048643         ] | 返回地址 (Return Address)
  -----------+-------------------------------+----------------------- 
  0xbffffc8c | [  0xbffffc94             ] | 保存的旧 %ebp (Saved %ebp) <--- %ebp
  0xbffffc88 | [         [?]             ] | 局部变量空间 (1)
  0xbffffc84 | [         [?]             ] | 局部变量空间 (2) - 缓冲区起点
  0xbffffc80 | [         [?]             ] | 局部变量空间 (3)
  0xbffffc7c | [         [?]             ] | 局部变量空间 (4)
  0xbffffc78 | [      0x00000001         ] | 保存的 %esi (Saved %esi)
  0xbffffc74 | [      0x00000002         ] | 保存的 %ebx (Saved %ebx) <--- %esp
  -----------+-------------------------------+-----------------------
  地址 (低)    |         (向下增长)          |
地址 (高)    |      栈内存内容 (十六进制)      |  溢出后的状态
  -----------+-------------------------------+-----------------------
  0xbffffc94 | [  0xbffffcxx             ] | (尚未被淹没)
  0xbffffc90 | [  0x080486 00            ] | 返回地址被覆盖!最后 43 变 00 (\0)
  -----------+-------------------------------+-----------------------
  0xbffffc8c | [  0x31 30 39 38          ] | Old EBP 被淹没!("8901")
  0xbffffc88 | [  0x37 36 35 34          ] | 缓冲区后半段 ("4567")
  0xbffffc84 | [  0x33 32 31 30          ] | 缓冲区前半段 ("0123") <--- 缓冲区起点
  -----------+-------------------------------+-----------------------
  0xbffffc80 | [         [?]             ] | 
  0xbffffc7c | [         [?]             ] | 
  0xbffffc78 | [      0x00000001         ] | 
  0xbffffc74 | [      0xbffffc84         ] | gets 参数 (指向 0xbffffc84)
  -----------+-------------------------------+-----------------------
  地址 (低)    |           (崩溃点)            |

3. 对抗防御 (Defenses)

这也是一场“道高一尺魔高一丈”的军备竞赛:

防御技术机制 (Mechanism)绕过思路 (Bypass)
Stack Canary (金丝雀)在 Return Address 之前插入一个随机值。函数返回前检查该值是否被修改。泄漏 Canary 值;爆破(Fork Server);覆盖异常处理链。
NX / DEP (不可执行)标记栈和堆为不可执行 (No-Execute)。ROP (利用代码段已有的指令)。
ASLR (地址随机化)每次运行程序时,栈、堆、库的位置随机变化。信息泄漏 (Info Leak);堆喷射 (Heap Spray)。