3

我正在尝试执行一个 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

上面的代码来自这里

当我用我的 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。我提前感谢。

4

1 回答 1

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 位的更多信息,请查看相关的维基百科文章

于 2019-06-30T21:07:32.527 回答