Linux 커널 5.8+에서 쉘코드를 실행하는 방법은 무엇입니까?

Linux 커널 5.8+에서 쉘코드를 실행하는 방법은 무엇입니까?

내가 실행하려는 어셈블리 코드는 단지 시스템 호출 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최종 코드를 얻으려면 assemble, 와 연결하세요.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)에서 최종 실행 파일을 실행하려고 하면 segfault가 발생합니다.

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

또는 쉘코드가 포함된 페이지에서 페이지 보호를 변경할 수 있습니다.

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

전반적인 변경 사항은 다음과 같습니다.당신이 찾은 것전체 취약점 클래스를 수정합니다. 위의 접근 방식을 사용하더라도 실행 중인 프로세스에 코드를 삽입하고 실행 가능한 스택을 요청하여 프로세스가 어느 정도 "협력"하지 않고는 이를 실행할 수 없습니다.

관련 정보