0

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
    xor eax, eax
    mov [rsp+8], al

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

    ; whoami
    push rax
    mov rcx, rsp
    mov word [rsp], 0x6877
    mov dword [rsp+2], 0x696d616f
    xor eax, eax
    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)

6
  • Does this stackoverflow.com/q/9960721/1606345 help? Commented Feb 12, 2024 at 8:31
  • no it doesn't work Commented Feb 12, 2024 at 10:37
  • When you run this under GDB, which instruction segfaults? Does disassembly show all the instructions present and correct as you single-step? (e.g. with layout asm). You didn't how what command you used to turn the machine code into a C string. That's where I'd suspect a problem, since you say it doesn't work with known-good testing code like How to get c code to execute hex machine code? either (and your mmap + memcpy looks reasonable. Commented Feb 12, 2024 at 11:13
  • And strace shows that mmap succeeded. BTW, your memcpy(dst,src, strlen(src)+1) could just be strcpy. Or memcpy(dst,src,sizeof(src)), but I guess you're using string stuff to verify that you don't have any 00 bytes. Commented Feb 12, 2024 at 11:18
  • assembly code breaks here at this instructions mov [rsp+8], al Commented Feb 12, 2024 at 11:22

1 Answer 1

1

You copied the shellcode bytes wrong. You seem to be missing 14 bytes. The correct version is:

#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\x69\xc7\x44\x24\x04\x6e\x2f\x73\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\x6d\x69\x31\xc0\x88\x44\x24\x06\x50\x51\x56\x57\x48\x89\xe6\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;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.