私が実行したいアセンブリコードは、システムコール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 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)で最終実行可能ファイルを実行しようとすると、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)();
}
}
全体的な変更は次のとおりです。あなたが見つけたもの完全な脆弱性クラスを修正します。上記のアプローチを使用しても、実行中のプロセスにコードを挿入して実行可能なスタックを要求して、プロセスがある程度「協力」しないと実行できません。