Linux-Kernel
如何在 Linux 核心 5.8+ 上執行 shellcode?
我試圖執行的彙編程式碼只是一個系統呼叫 60。
# exit.s .intel_syntax noprefix .section .text .globl _start _start: xor rax, rax mov al, 0x3c xor rdi, rdi xor rdi, 1 syscall
用 組裝它,用和
as exit.s -o exit.o
連結得到最終程式碼。ld exit.o -o exit``objdump -d exit
// ret.c const char shellcode[] = "\x48\x31\xc0\xb0\x3c\x48\x31\xff\x48\x83\xf7\x01\x0f\x05"; int main() { (*(void(*)())shellcode)(); }
我編譯使用
gcc -fno-stack-protector -z execstack -no-pie -o ret ret.c
在 Manjaro Linux(核心 5.10)和 Ubuntu(核心 5.8)上,嘗試執行最終執行檔時出現 seg 錯誤。
我在 Ubuntu 16.04(核心 4.4)上嘗試了同樣的方法,它完美無缺。
我做了一些研究,看起來這個送出可能改變了行為,但我不確定。
我的問題:如何讓上述程式碼在最新的核心版本上工作?
由於您要求一個可執行堆棧,因此將您的程式碼放在那裡將使其可執行:
int main() { const char shellcode[] = "\x48\x31\xc0\xb0\x3c\x48\x31\xff\x48\x83\xf7\x01\x0f\x05"; (*(void(*)())shellcode)(); }
或者,您可以更改包含 shellcode 的頁面上的頁面保護:
#include <stdio.h> #include <sys/mman.h> #include <unistd.h> const char shellcode[] = "\x48\x31\xc0\xb0\x3c\x48\x31\xff\x48\x83\xf7\x01\x0f\x05"; int main() { long page_size = sysconf(_SC_PAGESIZE); void *page_start = (void *) ((long) shellcode & -page_size); if (mprotect(page_start, page_size * 2, PROT_READ | PROT_EXEC)) { perror("mprotect"); } else { (*(void(*)())shellcode)(); } }
諸如您發現的更改的全部意義在於修復整類漏洞。即使使用上述方法,如果程序在某種程度上(通過請求可執行堆棧)不“合作”,您將無法將程式碼注入正在執行的程序並執行它。