如何在 Linux 内核 5.8+ 上运行 shellcode?

如何在 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 exitobjdump -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)上,我在尝试运行最终的可执行文件时遇到段错误。

我在 Ubuntu 16.04(内核 4.4)上尝试了同样的操作,并且运行完美。

我做了一些研究,看起来像这次提交可能改变了行为,但我不确定。

我的问题:如何让上述代码在最新的内核版本上运行?

答案1

由于您需要一个可执行堆栈,因此将代码放在那里将使其可执行:

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)();
  }
}

整体变化点如你找到的那个是修复整类漏洞。即使使用上述方法,如果进程没有在某种程度上“合作”(通过请求可执行堆栈),您也无法将代码注入到正在运行的进程中并执行它。

相关内容