BUUCTF wdb2018_guess题解:Canary绕过与栈溢出利用 1. 题目背景与初步分析BUUCTF是一个知名的CTFCapture The Flag竞赛平台而wdb2018_guess是其中一道经典的pwn题目。这道题目主要考察选手对Canary保护机制的绕过能力属于二进制安全领域的栈溢出类题目。Canary栈保护金丝雀是一种常见的栈溢出防护机制它通过在函数栈帧中插入一个随机值canary值在函数返回前检查该值是否被修改从而防止栈溢出攻击。要成功利用这类漏洞通常需要先泄露canary值再构造精确的ROP链或shellcode。2. 环境搭建与题目获取首先需要准备调试环境推荐使用以下工具组合Ubuntu 18.04/20.04 LTS与题目环境匹配pwntoolsPython漏洞利用框架gdb-peda增强版GDB调试工具checksec检查程序保护机制获取题目文件后先用checksec检查保护情况checksec --filewdb2018_guess预期输出会显示开启Canary和NX不可执行栈但未开启PIE地址随机化这为我们利用提供了重要线索。3. 逆向分析与漏洞定位使用IDA Pro或Ghidra对程序进行逆向分析重点关注以下函数main函数程序主逻辑存在漏洞的函数通常包含不安全的输入操作可能的信息泄露点关键发现程序中存在格式化字符串漏洞可以用于泄露内存信息存在栈溢出漏洞但受Canary保护程序加载了某些关键库函数如system4. Canary绕过技术详解4.1 Canary工作原理Canary通常位于栈帧的返回地址之前结构如下[局部变量][Canary][EBP][返回地址][参数]在函数返回前会检查Canary值是否被修改若被修改则立即终止程序。4.2 利用格式化字符串泄露Canary通过构造特定的格式化字符串如%n$p可以读取栈上指定位置的值。通过反复尝试可以定位到Canary在栈上的位置通常距格式化字符串参数6-8个偏移libc基地址用于计算system等函数地址程序基地址如果开启PIE关键payload示例payload b%7$p # 尝试泄露canary p.sendline(payload) canary int(p.recvline(), 16)4.3 构造精确溢出payload获取canary后需要构造包含以下部分的payload填充到canary位置的垃圾数据正确的canary值保持不被修改覆盖返回地址的ROP链或shellcode地址典型结构[垃圾数据填充][正确canary][EBP覆盖][目标地址][参数]5. 完整利用流程5.1 信息泄露阶段通过格式化字符串泄露canary值泄露libc基地址计算system地址确定其他关键地址如/bin/sh字符串5.2 构造ROP链根据泄露的信息构建ROP链调用system(/bin/sh)或使用one_gadget如果有合适条件5.3 发送最终payload精心构造的payload需要保持canary值不变精确覆盖返回地址设置好参数传递示例代码片段from pwn import * context(archamd64, oslinux) p process(./wdb2018_guess) # 第一阶段泄露canary p.sendlineafter(, %7$p) canary int(p.recvline(), 16) # 第二阶段构造ROP rop ROP(./wdb2018_guess) rop.system(next(elf.search(b/bin/sh))) payload flat( bA*offset, canary, bB*8, # 覆盖EBP rop.chain() ) p.sendline(payload) p.interactive()6. 调试技巧与注意事项6.1 常见问题排查Canary泄露位置不准确逐步尝试不同偏移%6$p到%15$p栈对齐问题在ROP链中添加ret指令调整栈对齐地址计算错误确保使用正确的libc版本6.2 GDB调试命令b *0x400123 # 在关键地址下断点 x/20xg $rsp # 查看栈内存 p canary # 查看canary值7. 防御措施与变种理解攻击方法后开发者可以采取以下防护完全禁用格式化字符串使用安全函数启用FORTIFY_SOURCE结合ASLR和PIE增加利用难度使用SSPStack Smashing Protector强化版这道题目的变种可能包括增加Canary随机化频率移除格式化字符串漏洞但保留其他信息泄露渠道改变内存布局增加定位难度