测试shellcode时出现分段错误

时间:2013-10-23 03:39:50

标签: segmentation-fault sigsegv shellcode

我正在尝试执行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的intel x86-32 CPU。 我提前感激。

1 个答案:

答案 0 :(得分:0)

您的问题是内存权限。旧的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