汇编版C代码推出shell

Assembly version of C code to launch a shell

在缓冲区溢出分配中,我得到了一个 C 文件 (call_shellcode.c),其中包含以下 C 代码的汇编版本,该代码执行以打开 shell:

#include <stdio.h>
#include <unistd.h>
int main(){
    char *name[2];
    name[0] = "/bin/sh";
    name[1] = NULL;
    execve(name[0], name, NULL);
}

文件 call_shellcode.c 中的代码是:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

const char code[] =
  "\x31\xc0"             /* xorl    %eax,%eax              */
  "\x50"                 /* pushl   %eax                   */
  "\x68""//sh"           /* pushl   [=12=]x68732f2f            */
  "\x68""/bin"           /* pushl   [=12=]x6e69622f            */
  "\x89\xe3"             /* movl    %esp,%ebx              */
  "\x50"                 /* pushl   %eax                   */
  "\x53"                 /* pushl   %ebx                   */
  "\x89\xe1"             /* movl    %esp,%ecx              */
  "\x99"                 /* cdql                           */
  "\xb0\x0b"             /* movb    [=12=]x0b,%al              */
  "\xcd\x80"             /* int     [=12=]x80                  */
;

int main(int argc, char **argv)
{
   char buf[sizeof(code)];
   strcpy(buf, code);
   ((void(*)( ))buf)( );
} 

我是通过命令编译的:

gcc -fno-stack-protector -z execstack -o call_shellcode call_shellcode.c

当我执行它时,它显示分段错误。哪里出错了?

这是使用 32 位 int 0x80 ABI 的 32 位 x86 机器码。

假设您使用的是普通的 x86-64 Linux 发行版,您将其编译为 64 位可执行文件,因此那些 push imm32 指令解码为 pushq,并且 RSP 在虚拟地址的低 32 位space。因此 int 0x80 将 return 与 eax=-EFAULT 并继续执行垃圾,导致段错误。

使用 strace 或 GDB 查看此内容(尽管 strace 在 64 位可执行文件中错误地解码 int 0x80,但它会正确显示 return 值)。参见

使用 gcc -m32 -z execstack .. 生成 32 位可执行文件,此机器代码将在其中运行。

使用下面的命令

gcc -z execstack -g -o call_shellcode call_shellcode.c