首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Shellcode返回而不是退出

从Shellcode返回而不是退出
EN

Stack Overflow用户
提问于 2019-12-18 06:39:17
回答 1查看 849关注 0票数 1

我正在为uni编写一个共享的任务,我已经“借来”和“按摩”了一些我在这里和其他地方看到的文章中看到的一些外壳代码。我已经能够构建一个运行在我的MacBook (Mojave)上的示例,并且几乎可以做我想做的事情。

但是,由于我对OS环境中的程序集编程没有那么丰富的经验(本例中是MacOS),而且由于我不完全理解下面的程序集,所以我需要一些帮助来克服我的最后一个问题。

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

如何修改程序集以返回而不是退出?

注意:如果被问到,我可以发布更多关于我正在使用的包装代码和工具的信息。

代码语言:javascript
复制
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样板代码,包括上面的外壳代码。

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-18 09:01:21

我有一个循环调用我的外壳代码

因此,如果这是一个实际的call,那么就可以开始了,唯一需要做的更改就是删除最后3个指令(movmovsyscall),并将它们替换为ret,因为返回地址已经在堆栈上了。但是我们需要额外地清理堆栈,因为文本字符串的地址是为了syscall而放在那里的,所以我们想在返回之前把它处理掉。

另外,由于外壳代码包含一个偏移量(第一个jmp操作码的值为0x24),所以不删除任何东西(因为它将改变偏移量),而是用NOP替换比较安全。除非您修改外壳代码的源代码并每次生成它,否则移除这些东西是很好的。

因此,我实际上要做的是用0x90(NOP)替换最后3个操作码的字节,然后用pop rax\ret替换最后2个字节,所以字节是0x580xc3。最后的外壳代码可能如下所示:

代码语言:javascript
复制
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\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x58\xc3\xe8\xd7\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21\x0d\x0a";
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59386678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档