• caglararli@hotmail.com
  • 05386281520

Unable to execute shellcode on x86_64 architecture

Çağlar Arlı      -    16 Views

Unable to execute shellcode on x86_64 architecture

I currently got interested in binary exploitation (even though I do not know if today is still useful).

I started studying shellcode and buffer overflow (stack-buffer overflow, specifically). I know that this vulnerability is nowadays rare, but I still want to lean how to perform it (I have to start somewhere). So I wrote this shellcode:

 section .text
    global _start

_start:

    xor rdx, rdx
    push rdx
    mov rax, 0x68732f2f6e69622f
    push rax
    mov rdi, rsp
    push rdx
    push rdi
    mov rsi, rsp
    xor rax, rax
    mov al, 0x3b
    syscall

and a C program to execute it:

char shellcode[] = "\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x31\xc0\xb0\x3b\x0f\x05";
int main(){
    void(*f)() = (void(*)())shellcode;
    f();
    return 0;
}

Though when I run it, I got SIGSEGV error.

This is what I get when I use strace:

execve("./exec", ["./exec"], 0x7ffe855b4e80 /* 57 vars */) = 0
brk(NULL)                               = 0x55f5dd4d6000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffcceb7b7b0) = -1 EINVAL (Invalid argument)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f913a4c2000
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=81189, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 81189, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f913a4ae000
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\0P<\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|0644, st_size=2072888, ...}, 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, 2117488, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f913a200000
mmap(0x7f913a222000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f913a222000
mmap(0x7f913a39a000, 360448, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19a000) = 0x7f913a39a000
mmap(0x7f913a3f2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1f1000) = 0x7f913a3f2000
mmap(0x7f913a3f8000, 53104, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f913a3f8000
close(3)                                = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f913a4ab000
arch_prctl(ARCH_SET_FS, 0x7f913a4ab740) = 0
set_tid_address(0x7f913a4aba10)         = 5515
set_robust_list(0x7f913a4aba20, 24)     = 0
rseq(0x7f913a4ac060, 0x20, 0, 0x53053053) = 0
mprotect(0x7f913a3f2000, 16384, PROT_READ) = 0
mprotect(0x55f5dc905000, 4096, PROT_READ) = 0
mprotect(0x7f913a4f7000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7f913a4ae000, 81189)           = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x55f5dc906010} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)

This is what I get running the program using GBD (peda):

RAX: 0x0 
RBX: 0x7fffffffde88 --> 0x7fffffffe1e7 ("/home/mastermind/Desktop/Hydrogen/shellcode/exec")
RCX: 0x555555557df8 --> 0x5555555550e0 (<__do_global_dtors_aux>:    endbr64)
RDX: 0x555555558010 --> 0x622fb84852d23148 
RSI: 0x7fffffffde88 --> 0x7fffffffe1e7 ("/home/mastermind/Desktop/Hydrogen/shellcode/exec")
RDI: 0x1 
RBP: 0x7fffffffdd70 --> 0x1 
RSP: 0x7fffffffdd58 --> 0x55555555514b (<main+34>:  mov    eax,0x0)
RIP: 0x555555558010 --> 0x622fb84852d23148 
R8 : 0x0 
R9 : 0x7ffff7fccfb0 (<_dl_fini>:    endbr64)
R10: 0x7ffff7fc88e8 --> 0xb00120000000e 
R11: 0x7ffff7fe1480 (<_dl_audit_preinit>:   endbr64)
R12: 0x0 
R13: 0x7fffffffde98 --> 0x7fffffffe217 ("SHELL=/bin/bash")
R14: 0x555555557df8 --> 0x5555555550e0 (<__do_global_dtors_aux>:    endbr64)
R15: 0x7ffff7ffd000 --> 0x7ffff7ffe2c0 --> 0x555555554000 --> 0x10102464c457f
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x555555558009:  adc    BYTE PTR [rbp+0x55],0x55
   0x55555555800d:  push   rbp
   0x55555555800e:  add    BYTE PTR [rax],al
=> 0x555555558010 <shellcode>:  xor    rdx,rdx
   0x555555558013 <shellcode+3>:    push   rdx
   0x555555558014 <shellcode+4>:    movabs rax,0x5068732f6e69622f
   0x55555555801e <shellcode+14>:   mov    rdi,rsp
   0x555555558021 <shellcode+17>:   push   rdx
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdd58 --> 0x55555555514b (<main+34>: mov    eax,0x0)
0008| 0x7fffffffdd60 --> 0x0 
0016| 0x7fffffffdd68 --> 0x555555558010 --> 0x622fb84852d23148 
0024| 0x7fffffffdd70 --> 0x1 
0032| 0x7fffffffdd78 --> 0x7ffff7c23a90 (<__libc_start_call_main+128>:  mov    edi,eax)
0040| 0x7fffffffdd80 --> 0x7fffffffde70 --> 0x7fffffffde78 --> 0x38 ('8')
0048| 0x7fffffffdd88 --> 0x555555555129 (<main>:    endbr64)
0056| 0x7fffffffdd90 --> 0x155554040 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000555555558010 in shellcode ()

Can you please help me figure out what the problem is here? I have tried countless times, changing the shellcode, analysing the program using GDB, but still the memory segmentation error present itself. If I am not able to execute the shellcode, I am not even able to exploit the stack-overflow vulnerability.

Thanks in advance for any useful answer.

Just as a side note:

  1. I compiled the program using: gcc -m64 -fno-stack-protector -z execstack -o exec exec.c

  2. Got the shellcode using objdump