从Shellcode返回而不是退出

时间:2019-12-18 06:39:17

标签: c macos assembly shellcode

我正在为uni分配共享内存,我已经“借用”和“按摩”了一些我在这里和其他地方阅读的帖子中看到的shellcode。我已经能够构造一个可以在MacBook(Mojave)上运行的示例,并且几乎可以完成我想要的操作。

但是,由于我没有在OS环境(本例中为MacOS)中进行汇编编程的经验,并且由于我不完全了解下面的汇编,因此我需要一点帮助来克服我的上一个问题。 / p>

在我的C样板包装器中,我有一个循环定期调用我的shellcode,但是该循环仅执行一次迭代。这使我得出结论,第二个syscall(在下面的代码中)正在执行exit 0,从而终止了该过程。

如何将程序集修改为 return 而不是 exit

注意,如果有要求,我可以发布有关我使用的包装器代码和工具的更多信息。

bits 64

Section .text
  global start

start:
  jmp       short MESSAGE     ;00000000  EB24              jmp short 0x26

GOBACK:
  mov       eax, 0x2000004    ;00000002  B804000002        mov eax,0x2000004  ; write
  mov       edi, 0x1          ;00000007  BF01000000        mov edi,0x1
  lea       rsi, [rel msg]    ;0000000C  488D3518000000    lea rsi,[rel 0x2b]
  mov       edx, 0xf          ;00000013  BA0F000000        mov edx,0xf
  syscall                     ;00000018  0F05              syscall

  mov       eax,0x2000001     ;0000001A  B801000002        mov eax,0x2000001  ;exit
  mov       edi,0x0           ;0000001F  BF00000000        mov edi,0x0
  syscall                     ;00000024  0F05              syscall


MESSAGE:
  call      GOBACK
  msg:      db      "Hello, world!", 0dh, 0ah
  .len:     equ     $ - msg

这是我的C样板代码,其中包括上面的shellcode。

#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

const char shellcode[] = "\xeb\x24\xb8\x04\x00\x00\x02\xbf\x01\x00\x00\x00\x48\x8d\x35\x18\x00\x00\x00\xba\x0f\x00\x00\x00\x0f\x05\xb8\x01\x00\x00\x02\xbf\x00\x00\x00\x00\x0f\x05\xe8\xd7\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21\x0d\x0a";

int main(int argc, char **argv)
{
  void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  memcpy(mem, shellcode, sizeof(shellcode));

  mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);

  for (int i = 0; i < 10; i++) {
    int (*func)();
    func = (int (*)())mem;
    (int)(*func)();
    sleep(5);
  }

  munmap(mem, sizeof(shellcode));

  return 0;
}

1 个答案:

答案 0 :(得分:2)

  

我有一个循环调用我的shellcode

因此,如果它是实际的call,那么您就很好了,唯一需要做的更改就是删除最后3条指令(movmov和{{1 }}),并用syscall替换它们,因为返回地址已经在堆栈中了。但是我们还需要稍微清理一下堆栈,因为文本字符串的地址是为了ret而放在这里,我们希望在返回之前将其清除。

此外,由于您的shellcode包含偏移量(第一个syscall操作码的值为jmp),因此不删除任何内容(因为它将更改偏移量)而是用{{1 }}。除非您修改shellcode的源代码并每次生成它-否则最好将其删除。

所以我实际上建议做的是用0x24(NOP)替换最后3个操作码的字节,用NOP替换最后3个操作码的字节{{ 1}}和0x90。最终的shellcode可能看起来像这样:

pop rax\ret
相关问题