Segmentation fault при вызове ассемблер-функции

В образовательных целях пишу программу, запускающую bash. В дальнейшем планируется запуск от root, но пока застрял на запуске assembler-функции из Си. Если собирать бинарник из ассемблер-кода, всё работает, но при запуске программы:

char shellcode[] ="\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\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();
}

Программа на ассемблере:

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

Компилирую так:

gcc -m64 -fno-stack-protector -z execstack -o exploit priv_escal.c

Segmentation fault выбрасывает на первой же строчке shellcode(). Пробовал на Ubuntu x64, Kali Linux x64 (подсистемы Windows). Ассемблер x64. Это какая-то защита ОС или ошибка кода?

    disass main
endbr64
push   rbp
mov    rbp,rsp
sub    rsp,0x10
lea    rax,[rip+0x2ed4]        # 0x4010 <shellcode>
mov    QWORD PTR [rbp-0x8],rax
mov    rdx,QWORD PTR [rbp-0x8]
mov    eax,0x0
call   rdx
mov    eax,0x0
leave
ret

Ответы (1 шт):

Автор решения: MysNikita

Решил проблему с помощью memory-mapping.

#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>

char shellcode[] = "\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x31\xc0\xb0\x3b\x0f\x05";
int main() {
    int shell_size = strlen(shellcode);
    void *memory = mmap(NULL, shell_size, PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
    memcpy(memory, shellcode, shell_size);
    int (*run)() = memory;
    run();
}
→ Ссылка