Linux-Kernel

如何在 Linux 核心 5.8+ 上執行 shellcode?

  • January 18, 2021

我試圖執行的彙編程式碼只是一個系統呼叫 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)();
 }
}

諸如您發現的更改的全部意義在於修復整類漏洞。即使使用上述方法,如果程序在某種程度上(通過請求可執行堆棧)不“合作”,您將無法將程式碼注入正在執行的程序並執行它。

引用自:https://unix.stackexchange.com/questions/629644