64位Ubuntu20.04下执行获取shell的Shellcode触发段错误
故障原因
段错误和ASLR配置无关,核心是内存权限不匹配:
你定义的全局shellcode数组会被编译到程序的.data段,该段默认权限为可读可写、不可执行。你编译时添加的-z execstack参数仅会将栈内存区域标记为可执行,不会修改.data段的权限,当程序跳转到shellcode地址尝试执行指令时,CPU会因内存页无执行权限直接触发段错误。
你使用的那段shellcode本身是64位Linux环境下正常的execve弹shell逻辑,不存在指令错误。
修复方案
二选一即可:
- 方案1:修改编译参数
保留原有其他编译选项,额外添加链接参数给数据段开放执行权限,完整编译命令如下:
其中gcc -O0 -fno-stack-protector -z execstack -Wl,-N getshell.c -o getshell-Wl,-N会告知链接器将程序的数据段、代码段统一标记为可读可写可执行,同时关闭数据段页对齐,shellcode所在内存页就能正常执行指令。 - 方案2:调整代码位置
把shellcode数组从全局作用域移到main函数的栈上,原有-z execstack参数就会让栈内存获得可执行权限,无需修改编译命令。修改后的代码如下:#include <stdio.h> int main() { unsigned char shellcode[] = "\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"; int (*ret)() = (int(*)())shellcode; ret(); }
补充:如果执行时依然报错,可以先通过
dmesg查看段错误日志,若错误码为15则依然是内存执行权限问题,若为其他错误码再排查shellcode对齐、系统调用号适配问题。
内容的提问来源于stack exchange,提问作者Taimoor Zaeem
相关产品推荐
相关产品推荐

