# 2020 程安 Pwn 筆記1
###### tags: `程式安全`
## Shellcode:
- 比較炫砲的machine code名字XD
- 因為通常希望跑完可以獲得shell所以叫shellcode
### Calling Convention
- AMD64 :
- userspace function:
- rdi rsi rdx <font color='red'>rcx</font> r8 r9
- system call:
- rdi rsi rdx <font color='red'>r10</font> r8 r9
- <font color='red'>rcx</font>存放userspace的rip,然後才跳進kernel mode load kernel space的rip
- `strace`指令可以dump出binary使用到的所有system call
### Mitigation -- NX
- NX(**N**o e**X**ecute)
- 任何segment都不可以同時有<font color='red'>寫跟執行</font>的權限
### Bypass NX
- 使用`mmap` system call 來assign一個特定權限的區塊
- ex
```c=
#include <sys/mman.h>
#include <stddef.h> //for def NULL
int main(){
void (*shell)() = mmap(NULL, 0x100, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1 ,0);
//map a rwx space for 0x100 byte
//PROT_EXEC :可執行. PROT_READ :可讀. PROT_WRITE :可寫
return 0;
}
```
- 執行`mmap`前

- 執行`mmap`後: 可以發現多了一段rwx權限的

- 或是用`mprotect` system call來修改權限(Protection)
## Buffer Overflow
- 因為沒有檢查輸入長度,輸入比buffer大的長度造成overflow
- ex. `gets(buf)`, `scanf(%s, buf)`等危險函數
沒有檢查輸入長度,就會造成bof
- 可以蓋掉return address,讓程式crash或執行到攻擊者想要執行的指令
### Mitigation -- Canary
- 在`old rbp`及`local variable`中間`(rbp-0x8)`塞一個從`fs+0x28`拿出來的隨機值,在程式`ret`之前進行檢查,如果不一樣就crash
- <font color='red'>canary的第一個byte一定是'\x00'</font>
### Bypass Canary
1. 在runtime時leak canary
- canary的第一個byte是00,而<font color='red'>printf是用`'\x00'`截斷</font>,因此蓋掉這個byte,會把canary後面的7byte也印出來
3. 如果buf不是線性的往下寫(ex可以跳到某個index開始寫),可以跳過canary所在的位置
### ROP(Return Oriented Programming)
- 現在的CTF題或現實環境幾乎都會開`NX` $\rightarrow$ 無法寫shellcode來get shell
也不會像某些簡單CTF題有個shell function可以直接使用
而且通常會開`Canary`的保護機制
$\Rightarrow$ 假設我們可以bypass Canary,該怎麼get shell?
-
- ROP chain: 由多個rop gadget組成
- rop gadget:
因為x64的assembly長度不固定,machine code使用dynamic抓長度,因此就算gadget是在某個指令的中間,只要符合對應的machine code就可以執行
- 每個rop gadget都以`ret`指令結尾,用來串起下一個gadget
- 把return address蓋成rop chain的第一個gadget
#### Mitigation -- ASLR and PIE
- ASLR(address space layout randomization)
- 由<font color='red'>系統</font>決定 ` /proc/sys/kernel/randomize_va_space`
- 0: 沒有ASLR
1: share library, stack位置不固定
2: share library, stack, heap位置不固定
- 其實就是在前面加上一段不定長度的空間
- PIE(Position independent executable)
- 由binary自行決定(compile時下`gcc -fpie -pie`)
- 在.text段前加上一段不定長度的空間
- 目地都是要讓攻擊者找不到gadget的真正位置,無法做ROP
#### bypass ASLR/PIE
- leak出那段random offset的長度
- stack上殘存的`libc function的address - vmmap看到的libc base` = 該function在libc中的`offset`
再利用bof leak出每次執行的`libc function address - offset`就是該次的libc base
### GOT (Global offset Table)
- 當有ASLR時,library每次都會被load在不同address
- 要怎麼讓他在執行時可以找到?
- Overview

1. GOT table中,哪個function在哪個offset是固定的
2. call funcA時會跳到funcA@plt上
```c=
funcA@plt
push [.got+0x10] //0x10為funcA在GOT中的offset