【问题标题】:Segmentation fault when testing shellcode测试 shellcode 时出现分段错误
【发布时间】:2013-10-23 03:39:49
【问题描述】:

我正在尝试执行一个 shellcode,但是我在执行它时遇到了问题。 (我使用的是 x86 32 位 CPU)

char shellcode[] =
                                      // <_start>
          "\x31\xc9"                  // xor    %ecx,%ecx
          "\xf7\xe1"                  // mul    %ecx
          "\x51"                      // push   %ecx
          "\x68\x2f\x2f\x73\x68"      // push   $0x68732f2f
          "\x68\x2f\x62\x69\x6e"      // push   $0x6e69622f
          "\x89\xe3"                  // mov    %esp,%ebx
          "\xb0\x0b"                  // mov    $0xb,%al
          "\xcd\x80"                  // int    $0x80

以上代码来自here

当我使用我的 gdb 调试器进行调试时,带有地址的汇编代码如下所示

0xbffff6e6: xor    %ecx,%ecx
0xbffff6e8: mul    %ecx
0xbffff6ea: push   %ecx
0xbffff6eb: push   $0x68732f2f
0xbffff6f0: push   $0x6e69622f
0xbffff6f5: mov    %esp,%ebx
0xbffff6f7: mov    $0xb,%al
0xbffff6f9: int    $0x80
0xbffff6fb: add    %al,(%eax)
0xbffff6fd: jmp    0xbffff727

问题是... 当我在 0xbffff6e6 处中断时,我无法执行下一条指令 mul %ecx 当我继续时,gdb 调试器给了我这个错误

Program received signal SIGSEGV, Segmentation fault.
0xbffff6e6 in ?? ()

据我所知,当我尝试访问不允许访问的内存地址时会发生分段错误。

我怎样才能让它在我的电脑上运行?同样,我在 Ubuntu Linux 上使用英特尔 x86-32 CPU。 我提前感谢。

【问题讨论】:

  • 那是因为数据段是不可执行的,它只有读和写权限。
  • 谢谢你的回答:-) 应该是!!那么我怎样才能让我的 shell 代码可以运行呢?当我用谷歌搜索时,它说我可以使用 mprotect 功能来授予可执行权限。这样对吗?或者有其他方法吗??
  • 查看ld 命令可选部分属性以使您的数据段可执行。但是,无法通过修改内存中的程序映像来实现这一点。只能修改ELF部分,再次运行程序。

标签: segmentation-fault shellcode


【解决方案1】:

您的问题是内存权限。旧的 shellcode 和编写它们的教程没有考虑多年来引入的安全保护。

您遇到的是当为您的 shellcode 所在的内存区域设置 NX(不执行)位时会发生什么。第一条指令会运行,但后续指令会产生段错误。

有两种方法可以运行该代码。一种是在禁用保护的情况下编译它。这样的事情对我有用:

bash $ gcc -m32 -g -fno-stack-protector -z execstack -o orig code.c -w
bash $ ./orig
$ uname
Linux
$ 

如果您想在启用现代保护的情况下运行 shellcode,您需要确保它从有权执行的内存区域运行。所以,如果你让你的程序像这样,它应该可以工作:

#include <sys/mman.h>
#include <errno.h>

char shellcode[] =
                                      // <_start>
          "\x31\xc9"                  // xor    %ecx,%ecx
          "\xf7\xe1"                  // mul    %ecx
          "\x51"                      // push   %ecx
          "\x68\x2f\x2f\x73\x68"      // push   $0x68732f2f
          "\x68\x2f\x62\x69\x6e"      // push   $0x6e69622f
          "\x89\xe3"                  // mov    %esp,%ebx
          "\xb0\x0b"                  // mov    $0xb,%al
          "\xcd\x80"                  // int    $0x80
  ;

void main() {
  char *buf;
  int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
  int flags = MAP_PRIVATE | MAP_ANONYMOUS;

  buf = mmap(0, sizeof(shellcode), prot, flags, -1, 0);
  memcpy(buf, shellcode, sizeof(shellcode));

  ((void (*)(void))buf)();
}

有关 NX 位的更多信息,请查看relevant wikipedia article。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 2016-12-17
    • 1970-01-01
    • 2014-03-17
    • 2016-03-28
    相关资源
    最近更新 更多