12Şub
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)