Linux下GDB调试C语言缓冲区溢出:操作流程困惑求助
栈溢出绕过密码验证的实操步骤
1. 编译目标程序
使用指定参数编译C源码,关闭栈保护和位置无关执行(PIE),确保内存地址固定且无栈溢出检测:
gcc -fno-stack-protector -no-pie -o pw_check pw_check.c
2. 用GDB分析栈布局与目标地址
2.1 确定输入数组到返回地址的偏移
启动GDB调试程序:
gdb ./pw_check
反汇编IsPassOk函数,查看栈结构:
disassemble IsPassOk
观察栈帧:char Pass[12]占12字节,函数调用时会保存基址指针(EBP/RBP),32位系统中EBP占4字节,64位系统中RBP占8字节,部分场景下栈会做对齐处理(比如64位下将12字节的Pass对齐到16字节)。
通过断点测试偏移:在gets(Pass)处下断点,输入特定字符(如16个'A'),查看EIP/RIP是否被覆盖,最终确定从Pass数组起始到返回地址的总偏移量:
- 32位系统:通常为
12(Pass长度) + 4(EBP) = 16字节 - 64位系统:通常为
16(对齐后的Pass长度) + 8(RBP) = 24字节
2.2 获取"Access granted!"分支的地址
反汇编main函数,找到printf("Access granted!")对应的指令地址:
disassemble main
在输出中定位到else分支的printf语句,记录其起始地址(比如32位下可能是0x08048568,64位下可能是0x555555555186,具体以调试结果为准)。
3. 构造溢出Payload
根据偏移量和目标地址构造Payload,注意x86/x86_64架构默认小端字节序:
- 32位示例:16个填充字符(如'A') + 目标地址的小端字节(例如地址
0x08048568对应\x68\x85\x04\x08) - 64位示例:24个填充字符 + 目标地址的小端字节(例如地址
0x555555555186对应\x86\x51\x55\x55\x55\x55\x00\x00)
用以下方式生成Payload(以32位为例):
printf 'AAAAAAAAAAAAAAAA\x68\x85\x04\x08' > payload.txt
4. 执行溢出测试
通过输入重定向传入Payload,触发栈溢出并跳转到授权分支:
./pw_check < payload.txt
成功的话会直接输出Access granted!,无需输入正确密码。
内容的提问来源于stack exchange,提问作者kuminoff
相关产品推荐
相关产品推荐

