1. 实验环境准备与前置知识在开始Attack Lab之前我们需要先搭建实验环境并理解几个关键概念。这个实验需要用到Linux系统推荐使用Ubuntu 18.04或更高版本。实验文件可以从课程官网下载解压后会得到ctarget和rtarget两个可执行文件分别对应缓冲区溢出攻击和ROP攻击的目标程序。首先需要掌握几个核心概念call指令会将返回地址下一条指令的地址压入栈中然后跳转到目标函数ret指令从栈顶弹出返回地址并跳转到该地址栈内存布局栈是从高地址向低地址增长的栈顶指针rsp指向当前栈顶位置小端模式x86架构采用小端字节序低位字节存储在低地址建议先用objdump反汇编两个目标程序objdump -d ctarget ctarget.d objdump -d rtarget rtarget.d2. Phase 1基础缓冲区溢出攻击第一个阶段的目标是通过缓冲区溢出修改返回地址使程序跳转到touch1函数而非正常返回。我们先分析getbuf函数的汇编代码00000000004017a8 getbuf: 4017a8: 48 83 ec 28 sub $0x28,%rsp 4017ac: 48 89 e7 mov %rsp,%rdi 4017af: e8 8c 02 00 00 callq 401a40 Gets 4017b4: b8 01 00 00 00 mov $0x1,%eax 4017b9: 48 83 c4 28 add $0x28,%rsp 4017bd: c3 retq关键点sub $0x28,%rsp 分配了40字节的栈空间Gets函数从标准输入读取数据到栈缓冲区我们需要覆盖返回地址使其指向touch1攻击步骤用40字节垃圾数据填满缓冲区接着写入touch1的地址0x4017c0注意小端序最终payload应为40个00 c0 17 40 00 00 00 00 00用GDB验证栈布局gdb ctarget break getbuf run -q x/80xb $rsp3. Phase 2注入代码攻击第二阶段需要在缓冲区中注入机器代码将cookie值传递给touch2函数。我们需要编写汇编代码将cookie存入rdimov $0x59b997fa, %rdi ret编译并反汇编获取机器码gcc -c inject.s objdump -d inject.o构造攻击字符串前8字节注入的机器码48 c7 c7 fa 97 b9 59 c3中间32字节填充数据最后8字节缓冲区起始地址用于跳转到注入代码再8字节touch2地址关键技巧注入代码地址可以通过GDB查看rsp值获得注意ret指令会继续从栈中读取下个地址4. Phase 3字符串参数攻击第三阶段需要传递字符串形式的cookie给touch3。由于字符串需要持久存储我们将其放在不会被覆盖的栈位置。步骤将cookie转为ASCII码35 39 62 39 39 37 66 61确定字符串存储位置如返回地址之后构造注入代码将字符串地址存入rdi跳转到touch3典型payload结构[注入代码地址] [字符串地址] [touch3地址] [cookie字符串]5. Phase 4ROP攻击基础从第四阶段开始我们需要使用ROPReturn-Oriented Programming技术攻击rtarget。ROP利用程序中现有的代码片段gadgets构造攻击链。关键步骤在farm.c中查找可用gadgets构造ROP链每个gadget以ret结尾通过栈控制执行流常用gadgetspop %rax; retmov %rax, %rdi; ret示例实现将cookie值传入rdi[pop rax gadget地址] [cookie值] [mov rax,rdi gadget地址] [touch2地址]6. Phase 5高级ROP攻击最后阶段需要克服栈随机化ASLR的影响动态计算字符串地址。我们使用以下策略获取当前栈指针值通过mov %rsp, %rax计算字符串与栈指针的固定偏移使用add_xy函数计算字符串绝对地址将结果传入rdi并调用touch3ROP链构造mov rsp,rax - mov rax,rdi - pop rsi - 偏移量 - add_xy - mov rax,rdi - touch3 - cookie字符串关键点每个-代表一个gadget和其参数需要通过farm.c仔细查找合适的gadget序列偏移量需要通过调试确定7. 调试技巧与常见问题在实验过程中有几个实用的调试技巧使用GDB的layout asm和layout regs同时查看代码和寄存器用x/80xb $rsp查看栈内存布局重点观察ret指令执行前后的rsp和rip变化对于ROP攻击可以单步执行每个gadget验证效果常见问题解决段错误检查地址是否有效栈是否对齐攻击失败确认cookie值和函数地址是否正确奇怪的跳转检查字节序和小端存储ROP链断裂确保每个gadget正确返回8. 安全启示与防御措施通过这个实验我们可以理解几种常见防御机制栈不可执行NX防止代码注入促使ROP出现栈随机化ASLR增加预测地址难度栈保护Canary检测缓冲区溢出代码签名防止恶意代码执行现代系统通常组合使用这些技术使得漏洞利用变得极具挑战性。作为开发者应该始终检查缓冲区长度使用安全函数如strncpy代替strcpy启用所有安全编译选项定期进行安全审计这个实验从攻击者角度让我们深入理解了系统安全机制的工作原理对开发安全软件很有帮助。建议在完成基础实验后可以尝试绕过更多保护机制或者自己实现简单的防御措施。