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

全体的な変更は次のとおりです。あなたが見つけたもの完全な脆弱性クラスを修正します。上記のアプローチを使用しても、実行中のプロセスにコードを挿入して実行可能なスタックを要求して、プロセスがある程度「協力」しないと実行できません。

関連情報