• caglararli@hotmail.com
  • 05386281520

why does my shellcode segfault assembly x86-64bit?

Çağlar Arlı      -    17 Views

why does my shellcode segfault assembly x86-64bit?

When I compile my shellcode and run it, Strace does not show an error. When I use my shellcode tester, I get a segmentation fault. I don't know why, maybe there's a smarter guy than me who can help me solve the problem I've been having for a few days.

The 32bit version of my shellcode is running fine.

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 rax
    mov rdi, rsp
    mov dword [rsp], 0x69622f2f
    mov dword [rsp+4], 0x68732f6e
    mov [rsp+8], al

    ; -c
    push rax
    mov rsi, rsp
    mov word [rsp], 0x632d
    mov [rsp+2], al

    ; whoami
    push rax
    mov rcx, rsp
    mov word [rsp], 0x6877
    mov dword [rsp+2], 0x696d616f
    mov [rsp+6], al

    push rax
    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

My shellcode tester:


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

# define EXEC_MEM ((void *) 0x80000000)

int main() {
    char shellcode[] = "\x48\x31\xc0\x48\x31\xd2\x50\x48\x89\xe7\xc7\x04\x24\x2f\x2f\x62\xc7\x44\x24\x04\x6e\x2f\x68\x31\xc0\x88\x44\x24\x08\x50\x48\x89\xe6\x66\xc7\x04\x24\x2d\x63\x31\xc0\x88\x44\x24\x02\x50\x48\x89\xe1\x66\xc7\x04\x24\x77\x68\xc7\x44\x24\x02\x6f\x61\x69\x31\xc0\x88\x44\x24\x06\x50\x51\x56\x57\x48\x89\xe6\x6a\x3b\x58\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;
}

My shellcode got compiled with:

nasm -f elf64 -o 'shellcode.o' 'shellcode.asm' && ld -m elf_x86_64 -o 'shellcode' 'shellcode.o'

My shellcode tester got compiled with:

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

i expect that my assembly code is correct.

Strace output from shellcode tester:


execve("/home/jobsi/Desktop/tester", ["/home/jobsi/Desktop/tester"], 0x7fffffffe050 /* 45 vars */) = 0
brk(NULL)                               = 0x405000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fffffffdef0) = -1 EINVAL (Invalid argument)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fbe000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=75159, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 75159, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fab000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\203\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2105184, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 2150256, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7c00000
mmap(0x7ffff7c26000, 1568768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7ffff7c26000
mmap(0x7ffff7da5000, 348160, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a5000) = 0x7ffff7da5000
mmap(0x7ffff7dfa000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1f9000) = 0x7ffff7dfa000
mmap(0x7ffff7e00000, 53104, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7e00000
close(3)                                = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fa8000
arch_prctl(ARCH_SET_FS, 0x7ffff7fa8740) = 0
set_tid_address(0x7ffff7fa8a10)         = 13347
set_robust_list(0x7ffff7fa8a20, 24)     = 0
rseq(0x7ffff7fa9060, 0x20, 0, 0x53053053) = 0
mprotect(0x7ffff7dfa000, 16384, PROT_READ) = 0
mprotect(0x403000, 4096, PROT_READ)     = 0
mprotect(0x7ffff7ffb000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7ffff7fab000, 75159)           = 0
mmap(0x80000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x80000000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)