注入的 64 位 shellcode 不会执行系统调用

Injected 64 bit shellcode wont execute syscall

我目前正在尝试将打印 helloworld 的代码注入易受攻击的程序中。通过将代码存储在其中一个环境变量中并覆盖 rip 寄存器以指向该代码,我成功地注入了代码。 这是我的汇编代码和操作代码:

 0000000000000000 <_start>:
   0:   eb 17                   jmp    19 <stack_setup>

0000000000000002 <execute>:
   2:   48 31 c0                xor    %rax,%rax
   5:   b0 01                   mov    [=10=]x1,%al
   7:   48 31 ff                xor    %rdi,%rdi
   a:   48 ff c7                inc    %rdi
   d:   5e                      pop    %rsi
   e:   b2 0f                   mov    [=10=]xf,%dl
  10:   0f 05                   syscall 
  12:   b0 3c                   mov    [=10=]x3c,%al
  14:   48 ff cf                dec    %rdi
  17:   0f 05                   syscall 

0000000000000019 <stack_setup>:
  19:   e8 e4 ff ff ff          callq  2 <execute>
  1e:   48                      rex.W
  1f:   65                      gs
  20:   6c                      insb   (%dx),%es:(%rdi)
  21:   6c                      insb   (%dx),%es:(%rdi)
  22:   6f                      outsl  %ds:(%rsi),(%dx)
  23:   2c 20                   sub    [=10=]x20,%al
  25:   77 6f                   ja     96 <stack_setup+0x7d>
  27:   72 6c                   jb     95 <stack_setup+0x7c>
  29:   64 21 0a                and    %ecx,%fs:(%rdx)
  2c:   0d                      .byte 0xd

第19行之后的操作码是针对指令db "Hello, world!", 0x0a, 0x0d。在用 gdb 检查 x2-x10 行指令的执行后,我注意到它正确地准备了参数来打印字符串 Hello, World。但是,在执行系统调用语句时,什么也没有发生。对于行 x12 - x17 中的指令也是如此。

我也试过编译link汇编代码来独立执行它并且它工作正常。除此之外,我还使用

选项编译了易受攻击的程序
  -fno-stack-protector -z execstack

这样我就可以运行代码位于栈中。我还禁用了 randomizing_va_space。我想问一下是不是有什么我没有做的,让我成功执行我注入的代码?

原因可能是 write 系统调用 returns 一个错误代码。这可能有很多原因,但也许 rdx 并不全是零,所以你应该 xor %rdx, %rdx 在加载 15 之前(实际上你应该只加载 14,因为 "Hello, World!\n")。

无论如何,来自 write 的错误将在 rax 中返回,并且是一个负数 (-errno),因此当您执行

mov    [=10=]x3c,%al
dec    %rdi
syscall 

这将是一个无效的系统调用,errno 38 for ENOSYS 将被返回。

exit 无论如何我都要工作

xor    %rax, %rax 
mov    [=11=]x3c,%al
syscall

我建议您 运行 使用 strace 的程序,并从其输出中查看 write 失败的确切原因。


下面是适合我的 shell 代码版本:

0000000000000000 <main>:
   0:   eb 1d                   jmp    1f <stack_setup>

0000000000000002 <execute>:
   2:   48 31 c0                xor    %rax,%rax
   5:   b0 01                   mov    [=12=]x1,%al
   7:   48 31 ff                xor    %rdi,%rdi
   a:   48 ff c7                inc    %rdi
   d:   5e                      pop    %rsi
   e:   48 31 d2                xor    %rdx,%rdx
  11:   b2 0e                   mov    [=12=]xe,%dl
  13:   0f 05                   syscall 
  15:   48 31 c0                xor    %rax,%rax
  18:   b0 3c                   mov    [=12=]x3c,%al
  1a:   48 ff cf                dec    %rdi
  1d:   0f 05                   syscall 

000000000000001f <stack_setup>:
  1f:   e8 de ff ff ff          callq  2 <execute>
  24:   48                      rex.W
  25:   65 6c                   gs insb (%dx),%es:(%rdi)
  27:   6c                      insb   (%dx),%es:(%rdi)
  28:   6f                      outsl  %ds:(%rsi),(%dx)
  29:   2c 20                   sub    [=12=]x20,%al
  2b:   57                      push   %rdi
  2c:   6f                      outsl  %ds:(%rsi),(%dx)
  2d:   72 6c                   jb     9b <stack_setup+0x7c>
  2f:   64 21 0a                and    %ecx,%fs:(%rdx)