【问题标题】:Executed shellcode terminates main program执行的 shellcode 终止主程序
【发布时间】:2017-05-11 19:47:12
【问题描述】:

我正在尝试在内存区域中执行 shellcode。虽然到目前为止它工作正常,但我现在面临另一个问题:在我调用 shellcode-program 后 main-c-program 退出。除了使用线程之外,有没有(简单的)方法?

我认为这与mov rax, 60和下面的syscall有关,退出程序。对吧?

主 C 代码

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

const char shellcode[] = "\xeb\x1e\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x5e\xba\x0d\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05\xe8\xdd\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
  // Allocate some read-write memory
  void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  // Copy the shellcode into the new memory
  memcpy(mem, shellcode, sizeof(shellcode));

  // Make the memory read-execute
  mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);

  // Call the shellcode
  void (*func)();
  func = (void (*)())mem;
  (void)(*func)();

  // This text will never appear
  printf("This text never appears");

  // Now, if we managed to return here, it would be prudent to clean up the memory:
  // (I think that this line of code is also never reached)
  munmap(mem, sizeof(shellcode));

  return 0;
}

Shellcode 的基础(汇编程序(英特尔))

global _start

_start:
    jmp message

code:
    mov     rax, 1
    mov     rdi, 1
    pop     rsi
    mov     rdx, 13
    syscall

    mov    rax, 60
    mov    rdi, 0
    syscall

message:
    call code
    db "Hello, World!"

【问题讨论】:

    标签: c assembly execute terminate shellcode


    【解决方案1】:

    imo 最简单的方法是制作一个二进制文件,然后执行 exec() 。如果你需要输出然后设置管道。

    【讨论】:

    • 我想从内存段执行代码,用shellcode更容易吧?还有其他想法吗?
    【解决方案2】:

    其实是我自己发现的。如果有人有兴趣,简单的解决方案是按如下方式更改汇编代码:

    global _start
    
    _start:
        jmp message
    
    code:
        mov     rax, 1
        mov     rdi, 1
        pop     rsi
        mov     rdx, 13
        syscall
    
        ret        # Instead of "mov.., mov..., syscall"
    
    message:
        call code
        db "Hello, World!"
    

    【讨论】:

    • jmp-call-pop 代码应该在没有“ret”指令的情况下工作。至少它适用于我使用更简单的 C 程序。此外,该“ret”指令最终可能会产生意想不到的后果,因为它将地址(或任何存在的)从堆栈顶部弹出。因此,当您的 C 代码执行这部分代码时,没有在汇编代码中设置堆栈帧,您的下一条指令可能会使程序崩溃;从而破坏了 shellcode 的意图。
    • @InfinitelyManic 我将整个东西转移到 ARM 汇编代码中(因为那是我真正需要的),这不起作用。跳过“ret”(或 ARM 中的“bx lr”)会导致分段错误。
    • 您的意思是您将 x86-64 代码移植到 ARMv7 代码 - 对吧?您的 ARM 代码是否在您的主 C 程序中正确执行?
    • @InfinitelyManic 我们移植了 ARM 代码,但代码本身可以工作。我们使用以下代码:mov r0, #1mov r1, stringmov r2, #12mov r7, #1swi 0mov r7, #1swi 0string:.ascii "Hello, World"我们将其转换为shellcode,但这仍然存在于我们的主C程序中。省略最后一个系统调用或用bx lr 替换它会导致段错误。有什么想法吗?
    • 刚刚修复它,当我在另一个程序中执行此代码时,我们需要与 mv r7, #0swi 0 不同的东西。相反,我在开头添加了push {r0-r7, lr},在末尾添加了pop {r0-r7, pc}bx lr,而不是系统调用。这在看起来像在另一个程序中执行时有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多