x86-64 Linux缓冲区溢出利用失败,求问题排查与解决
可能的问题排查方向
返回地址长度错误:x86_64架构下,栈上的返回地址是8字节(64位),你提到“加6字节返回地址”明显不符合架构要求,这会导致返回地址覆盖不完整,程序跳转到非法地址,直接触发SIGSEGV或SIGILL。重新计算偏移量时,要确保覆盖的是完整的8字节返回地址。
偏移量与实际栈布局不符:GDB调试环境会额外添加环境变量和调试相关栈结构,导致GDB内的栈地址和程序直接运行时的栈地址存在差异。可以在目标程序中添加代码打印栈地址(比如
printf("%p\n", &buffer);),对比GDB内的地址,确认偏移量和返回地址的准确性。Shellcode上下文兼容性问题:单独运行的shellcode通常在干净的寄存器环境下执行,但目标程序溢出前的寄存器状态可能被修改(比如某些寄存器被用作函数参数或临时变量),导致shellcode依赖的寄存器值不符合预期。比如你写的execve shellcode如果依赖
rax、rdi等寄存器的初始值,而目标程序溢出时这些寄存器的值不对,就会触发非法指令。编译选项未完全生效:检查编译命令是否确实关闭了所有防护:
- 关闭栈金丝雀:
-fno-stack-protector - 关闭DEP/NX:
-z execstack - 关闭RELRO:
-z norelro - 关闭PIE:
-no-pie - 禁用优化:
-O0(避免编译器修改栈结构)
缺少任何一项都可能导致溢出失败。
- 关闭栈金丝雀:
Shellcode注入位置错误:如果将shellcode放在返回地址之前,而偏移量计算错误,会导致返回地址跳转到shellcode的中间而非开头,触发SIGILL;如果放在返回地址之后,要确保栈空间足够,且返回地址指向NOP滑条的起始位置(而非shellcode开头,避免栈上的随机字节破坏shellcode)。
内容的提问来源于stack exchange,提问作者AISK
相关产品推荐
相关产品推荐

