为什么我会收到分段错误?(测试Shellcode)

9
我写了一个简单的ASM文件并在我编写的C文件中运行它。结果我遇到了一个段错误。但是,当我执行已编译的ASM文件时,没有错误发生。
我正在运行64位,并使用32位shellcode。这是问题吗?
不可能,因为我使用下面的代码却一直得到段错误:
char shellcode[] = "\x90"; //simple NOP in ASM
int main(int argc, char **argv)
{
  int (*ret)();
  ret = (int (*)()) shellcode;
  (int)(*ret)();
}

请问有人能运行这个程序并告诉我是否报分段错误吗?我已经尝试了3到4个其他的C文件,但都无法正常工作。

更新:

((void(*)(void))code)();

似乎可以使用这一行代码代替那三行代码。

1
这不是使用内联汇编的方法...首先,你使用的是哪个编译器?这里是如何在“gcc”中实现它的。 - Elliott Frisch
1
在哪个平台上(什么操作系统,什么编译器)?这可能是因为您的堆不可执行。 - Gilles 'SO- stop being evil'
在任何情况下,x86-64操作系统都不太可能允许您执行数据。 - Brett Hale
你好!感谢回复。我的朋友告诉我,我的 C 语言需要“大量改进”。使用 ((void(*)(void))shellcode)(); 是有效的。我对指针强制转换成函数语法感到困惑。 - Goodies
我之前问过一个非常类似的问题,并且由@Drew McGowen给出了一个相当好的答案:http://stackoverflow.com/q/25311861/1382251。 - barak manos
显示剩余6条评论
4个回答

12
如上所述,shellcode存储在非可执行内存中。请尝试使用启用了-fno-stack-protector和-z execstack标志的编译器重新编译程序。
即:
gcc -fno-stack-protector -z execstack -O OutputFileName yourShellCode.c

另外,您也可以在已经编译完成且没有这些补充参数的二进制文件上运行“execstack OutputFileName”。 - WhiteWinterWolf

3

两个问题:

  1. Shell代码可能位于非可执行内存中。为了使其可执行,您需要要求操作系统将其设置为可执行文件(例如使用mprotect(2)VirtualProtect()),或者分配新的可执行内存并将其复制到那里(例如使用mmap(2)VirtualAlloc())。
  2. 你的Shell代码没有返回/退出。在CPU执行该NOP指令(0x90)后,它将继续执行该NOP指令之后的内存中的代码。很可能会很快崩溃,但也可能做其他随机和不可预测的事情。

要解决问题2,您需要明确地执行返回指令(在x86 / x86-64上为C3)以从您的Shell代码返回,或者您需要执行永远不会返回的操作,例如调用exit(3)函数。


3
也许你应该更改你的变量:
   char shellcode[]

致:

   const char shellcode[]

就像这个问题中所示: segmentation-fault-error-when-exe-c

这个解决方案对我有用! :)


完成了! 操作系统:Arch Linux x86_64 内核版本:4.9.8-1-ARCH 运行时间:2小时41分钟 窗口管理器:i3 桌面环境:无 软件包数量:765 内存:2405 MB / 5963 MB 处理器类型:Intel(R) Core(TM) i5 CPU M 430 @ 2.27GHz $EDITOR:无 根目录:16G / 69G(23%)(ext4) - Evgeny Danilenko

2
尝试将shellcode放入主函数中,使其成为局部变量:
int main(int argc, char **argv)
{
  const char shellcode[] = "<your shellcode>";
  int (*ret)();
  ret = (int (*)()) shellcode;
  (int)(*ret)();
}

然后使用标志-fno-stack-protector-z execstack编译它:

gcc <filename>.c -fno-stack-protector -z execstack -o <filename>

我在stackexchange上发现了这个想法,对我很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接