Assembly x86-64Bit shellcode doesn't run execve syscall

97 views Asked by At

I am a newbie in writing assembler code / shellcodes. My shellcode should generate shell via syscall execve with an argument array. When I run the compiled shellcode it seems to work, I get my username printed on the command line and all arguments are correct, analyzed with the strace tool.

But when I run my shellcode with my shellcode tester, It doesn't passed the correct arguments to the execve function and i can't spawn a shell.

Thats my 64bit shellcode:


section .text

global _start

_start:
    ;execve
    ; - rax = syscall number (59, 0x3b)
    ; - rdi = const char *filename
    ; - rsi = const char *const *argv
    ; - rdx = const char *const *envp
    xor rax, rax
    xor rdx, rdx

    ; //bin/sh
    push rdx
    mov rbx, 0x68732f6e69622f2f
    push rbx
    mov rdi, rsp

    ; -c
    push rdx
    sub rsp, 2
    mov word [rsp], 0x632d
    lea rsi, [rsp]

    ; whoami
    push rdx
    sub rsp, 6
    mov word [rsp], 0x6877
    mov dword [rsp+2], 0x696d616f
    lea rcx, [rsp]

    push rdx
    push rcx
    push rsi
    push rdi
    mov rsi, rsp

    push 0x3b
    pop rax
    syscall

    ;exit
    ; - rax = syscall number (60, 0x3c)
    ; - rdi = int error_code
    push 0x3c
    pop rax
    shl rdi, 0x1
    neg rdi
    syscall

Thats my shellcodetester:


# include <stdio.h>
# include <string.h>
# include <unistd.h>
# include <sys/mman.h>

# define EXEC_MEM ((void *) 0x80000000)

int main() {
    const unsigned char shellcode[] = "\x48\x89\xe5\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x52\x48\xbb\x2f\x2f\x62\x69\x2f\x73\x68\x53\x48\x89\xe7\x52\x48\x83\xec\x02\x66\xc7\x04\x24\x2d\x63\x48\x8d\x34\x24\x52\x48\x83\xec\x06\x66\xc7\x04\x24\x77\x68\xc7\x44\x24\x02\x6f\x61\x69\x48\x8d\x0c\x24\x52\x51\x56\x57\x48\x8d\x34\x24\x6a\x3b\x58\x0f\x05\x6a\x3c\x58\x48\xd1\xe7\x48\xf7\xdf\x0f\x05";

    mmap(EXEC_MEM, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0);
    memcpy(EXEC_MEM, (void *)shellcode, strlen(shellcode)+1);
    (*(int (*)())EXEC_MEM)();
    return 0;
}

Compile shellcode:

nasm -f elf64 -o './shell-64Bit.o' './shell-64Bit.asm' && ld -m elf_x86_64 -o './shell-64Bit' './shell-64Bit.o'

Compile shellcodetester:

gcc -no-pie -fno-stack-protector -z execstack './shellcodetester.c' -o './shellcodetester'

Dump shellcode:

objdump -d './shell-64Bit'|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'

I debug with gdb the compiled shellcodetester and analyzed main function with disas main, and set a breakpoint at the last call instruction in the main function, then i stepped over the shellcode instruction with si.

I realized that my data gets popped off the stack and the registers have wrong values for unkown reason.

1

There are 1 answers

0
Marius Romeiser On
objcopy -Obinary './shell-64Bit' './shell-64Bit.bin'
hexdump -v -e '"\\""x" 1/1 "%02x" ""' './shell-64Bit.bin' 

That worked for me!