通过memcpy触发缓冲区溢出获取Shell遇段错误,求技术指导
栈溢出获取Shell失败的排查与解决
核心问题分析
这个函数存在明确的栈溢出漏洞:32字节的局部变量被写入600字节数据,会覆盖栈上的EBP、返回地址等关键区域。你遇到的段错误,核心原因基本是shellcode未完整存放、返回地址未指向shellcode,或shellcode本身不符合需求。
分步排查与解决
1. 明确shellcode的存放逻辑
栈溢出时,输入的600字节数据中:
- 前32字节会填充
variable数组 - 剩余568字节会依次覆盖栈上的EBP、返回地址,以及更靠后的栈空间
你的当前shellcode长度约40字节,超过了variable的32字节容量,导致shellcode被拆分为两部分(前32字节在variable,后8字节进入EBP区域),无法完整执行,直接触发段错误。
2. 调整shellcode的位置与构造溢出数据
根据shellcode长度,有两种构造方式:
- 短shellcode(长度<32字节):
把shellcode放在输入数据的前32字节范围内,后续填充垃圾数据直到覆盖返回地址的位置,最后将返回地址设置为variable的栈地址(让函数返回时跳转到shellcode起始位置)。 - 长shellcode(长度>32字节):
先填充32+4字节的垃圾数据(覆盖variable和EBP),之后跟上完整的shellcode,最后将返回地址设置为shellcode在栈上的起始地址。
3. 确定栈地址的具体值
需要通过gdb调试获取关键地址:
- 在
foo函数的memcpy处下断点 - 执行到断点时,查看
variable的栈地址(比如通过print &variable) - 根据溢出数据的构造方式,计算shellcode的起始地址,作为返回地址填入
4. 替换符合需求的shellcode
你当前使用的是执行cat /bin/flag.txt的shellcode,并非获取交互式shell的代码。如果目标是获取系统shell,建议使用32位Linux标准shellcode:
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80
该shellcode长度仅23字节,适合放入variable数组,执行execve("/bin/sh", ["/bin/sh"], NULL)获取交互式shell。
5. 检查程序的栈保护机制
用checksec命令查看程序是否开启栈金丝雀等保护:
checksec ./your_program
如果显示Stack: No canary found,则无需额外处理;若存在栈金丝雀,需先泄露金丝雀值再构造溢出数据(新手练习程序大概率未开启该保护)。
操作步骤总结
- 用
checksec确认程序保护状态 - 通过gdb调试获取
variable或shellcode的栈地址 - 选择合适的shellcode(推荐短shellcode简化操作)
- 构造溢出数据:垃圾数据 + shellcode + 目标返回地址
- 输入构造好的数据,测试获取shell
内容的提问来源于stack exchange,提问作者AzerSD
相关产品推荐
相关产品推荐

