# PWN週 - ROP (Return Oriented Programmimg)
:::info
【課程大綱】
- [環境準備](#課前環境準備)
- 套件安裝
- [課程開始](#課程開始)
- 大名鼎鼎的 ROP
- Q1: 什麼使用情境需要 - **bypass NX**
- Q2: 技術原理 - **bof + gadgets + Basic ROP**
- Q3: Calling Convention - **分別適用於 x86/x64 架構、 ROP Chain**
- Q4: 工具包介紹 - **ROPgadget**
- 來到 Lab 環節!
- 關於 ROP 的緩解方法
- [參考資料](#參考資料)
>[name= islab WIFI]
:::
# 環境準備
## 套件安裝
- **Pwntools** - 寫 payload 的好朋友
- **ROPgadget** - 用來找合適的 gadgets 們
- **pwndbg** or **gef** or **peda** - 就是不同的 GDB plug-in
# 課程開始
## 大名鼎鼎的 ROP
### Q1: 什麼使用情境需要 - bypass NX
* 主要是預防被寫入 shellcode,所以「可執行 segments 不可寫,可寫入的不可執行」
* 而 bypass 的方法,就是使用 ROP !
* 透過拼湊 binary 檔案中的程式小片段 Gadgets,達到控制 rip 或修改 register 的傳遞參數。
:::warning
接下來的教學範例與實作,**以 x64 (64-bits) 架構爲主** 。
:::
### Q2: 技術原理 - Return to Gadgets
#### Gadgets
- 透過 `ret` = `pop rip` 去執行其他包含 `ret` 的程式片段。
- 以下程式片段為 `ret` 結尾的範例:
1. 
2. 
3. 
#### Buffer Overflow
- 沒有檢查使用者輸入邊界的 function
- 透過 `gets()` 可從 user 的輸入讀取直到 EOF 或換行符號才停止。
- 或是 `strcpy()` 將原始 string 複製到 buffer。但複製的字串具體長度取決於原始字串的長度。

- 因此,想要控制程式流程,就是覆蓋 `return address` 上的儲存數值。
- 再者,藉由 `ret = pop rip` ,讓 `rip` 帶著被修改的值,跳去指定 address。
#### Basic ROP
``` c
//假設: 有一個正常程式流程不會跑到的 win function
void win ( parameter )
if ( parameter = 0xdeadbeef ){
FILE *fd = fopen("flag.txt", "r");
}
```






#### 小統整
> **Step1. Control Flow Hijacking**
> 在基礎的 ROP 概念中,透過 buffer overflow ,從 return address 獲得程式流程的控制權。
> **Step2. Gadget Chaining**
> 根據 calling convention 的「參數傳遞」順序,於程式片段中, 挑選你所需要的 gadgets 並拼湊起來。
> **Step3. Payload Execution**
> 撰寫 payload 串起前兩步驟,並搭配具有漏洞的程式開始執行時,就可以使用 chain of gadgets 做出超乎預期的行為。
### Q3: X86/X64 的架構下
#### 根據不同的 Calling Convention
> **X86 (32-bits)**
- 使用 stack 傳遞參數:
- 將 parameter 以輸入相反的順序(從右到左) push in stack。
> **X64 (64-bits)**
- 使用 register 傳遞參數或指針的順序:
- rdi -> rsi -> rdx -> rcx -> r8 -> r9
#### 知識小補充
> **X86 (64-bits)**
1. 假設為 Program 預設參數和指針在 stack 上的位置。

2. 可以覆蓋放在 function 後的 parameters,將被帶入執行function中。
> **X64 (64-bits)**
- 對於前幾個參數使用 registers 暫存與傳遞,相較於 x86 架構增加了更多的暫存器與擴大 address 空間。
同時,也提高了查找或鏈接合適 gadgets 的難度。
### Q4: 工具包介紹
[ROPgadget Tool](https://github.com/JonathanSalwan/ROPgadget)
#### 常用指令
- `--binary`: 指定的執行檔名稱。
- `--ropchain`: 自動生成 ROP Chain,但很有可能失敗,還是需要手工藝。
- `--only`: 使用正則表達式篩選合適的 gadgets。
- --only "pop|ret"
- `--string`: 查找單一指定的 string。
- --string win
## 來到 Lab 環節!
- 請先至雲端硬碟區,下載 Lab 的相關檔案 (o🪄'▽')o🪄
[G00gle Dr1ve 在此](https://drive.google.com/drive/folders/17o1iYlUNYYhi4aAvUvfzV3N9iVIDTmsA?usp=sharing)
### ret2text single
#### 題目敘述
> - 還記得 ret2win 嗎?
> - 我們來個進階版,這次你需要把 usefulstring 與 win 串接起來,才能夠獲得 Flag。
> - (hint: 使用 short ROP chain,重新組合 usefulstring 和 win )
#### Payload 填空
- **更改 ? 的內容**,以符合正確的 Basic ROP Payload。
- 需自行建立一個新檔案寫入 payload,並與 Lab 執行檔放在同個資料夾下。
``` python
from pwn import *
p = process("./split")
context.arch = 'amd64'
pop_rdi_ret = ?
useful_string = 0x601060
system = 0x40074b
# 32-bytes padding buffer + 8-bytes rbp
payload = b'a'*40
payload += p64(?)
payload += p64(?)
payload += p64(?)
p.sendline(payload)
p.interactive()
```
#### 題目參考資訊
- ghidra
- 
- 
- 
```
$ checksec
```

```
$ info functions
```

```
$ create pattern 0x30
$ pattern search 0x6161616161616165
```

#### 問與答
1. X64 calling convention 下,**第一個傳遞參數的 register** 為何?
2. 以此挑選合適的 gadgets。
:::spoiler 你要的是哪一個 gadget?
- [ ] 
- [ ] 
- [ ] 
:::
3. 符合題意,撰寫 payload 的正確順序為何?
4. 如果你已經下載好 pwntools ,嘗試將本題目 run 在你的 vm 上,查看是否可以成功獲取 **is1abPWN{}** 。
5. 祝你好運!
### ret2text multiple
#### 題目敘述
> - 如何從 ROP Chain 中連續 call functions 並且不會造成 crash?
> - 先不用逆向去看執行檔,直接把重點跟你說!
> - 必須按該順序呼叫 callme_one()、callme_two()和callme_three()函數。
> - 且每個函數都需要帶參數 0xdeadbeef, 0xcafebabe,0xd00df00d。
> 例如,在 x86_64 的範例是 callme_one(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d)。
#### Payload 填空
- **更改 ? 的內容**,以符合正確的 ROP Chain Payload。
- 需自行建立一個新檔案寫入 payload,並與 Lab 執行檔放在同個資料夾下。
``` python
from pwn import *
p = process("./callme")
context.arch = 'amd64'
para_1 = p64(0xdeadbeefdeadbeef)
para_2 = p64(0xcafebabecafebabe)
para_3 = p64(0xd00df00dd00df00d)
usefulGadgets = p64(?)
callme_one = p64(0x400720)
callme_two = p64(0x400740)
callme_three = p64(0x4006f0)
gadget_ret = p64(0x4006be)
# target_parameters
parameters = ?
parameters += para_1
parameters += para_2
parameters += para_3
# 32-bytes padding buffer + 8-bytes rbp
payload = b'a'*40
payload += ?
payload += ?
payload += ?
payload += ?
payload += ?
payload += ?
payload += ?
p.recvuntil(b'> ')
p.sendline(payload)
p.interactive()
```
#### 題目參考資訊
- ghidra
- 
```
$ checksec
```

```
$ objdump
```

```
$ create pattern 0x30
$ pattern search 0x6161616161616165
```

#### 問與答
1. X64 calling convention 下,**前三個傳遞參數的 register** 為何?
2. 以此挑選合適的 gadgets。
:::spoiler 你要的是哪一個 gadget?
- [x] 
- [ ] 
- [ ] 
:::
4. 符合題意,撰寫 payload 的正確順序為何?
5. 如果你已經下載好 pwntools ,嘗試將本題目 run 在你的 vm 上,查看是否可以成功獲取 **ROPE{}** 。
6. 祝你好運!
## 關於 ROP 的緩解方法
### 破解迷思之 ~~ASLR 可以阻擋 ROP 技巧~~
- 在開啟 ASLR 保護機制的情況下,並非所有位址都是隨機的。**如果同時有關閉 PIE ,.text address 是固定的,可以利用。**
- RX 權限: 即使能夠執行的只有 `.text 區域`,仍然可以從有限的程式片段中,找到並拼湊適合的 gadgets。
- **但是,如果從 .text 區域真的沒有想要用的 gadgets 呢?**
- 知道目標環境的 libc 版本,可以透過 leak 出 `libc 的位址`,使用 libc 中的程式片段建構 ROP。
### 注意使用者可輸入的 Buffer 大小
- **基礎 ROP 的攻擊手法:** 主要是使用 buffer overflow,達到控制程式流程 (控制 rip )。
- **Stack Canaries:** 如果在開啟 NX & ASLR 的狀況下,增加 canary 保護機制,則無法輕易覆蓋 `return address` 上的值來製作 ROP ,以此增加攻擊手法的困難性。
## 參考資料
【Stack Overflow】重要概念!!!
- ret2text
- ret2syscall
- ret2plt
- ret2libc
- GOT表洩漏
[Day 28 - Pwn 0x2](https://ithelp.ithome.com.tw/m/articles/10252772)
( stack overflow 的相關介紹)
[[Day8] Stack 攻擊手法 - ROP:靜態連結](https://ithelp.ithome.com.tw/articles/10356195)
( 從程式碼分析了解 ROP ,很新很詳細的文章 )
[ROP Chaining: Return Oriented Programming](https://www.ired.team/offensive-security/code-injection-process-injection/binary-exploitation/rop-chaining-return-oriented-programming#id-2nd-rop-chain)
( PPT 裡長得偏嚇人的流程圖出處 )
[PWN|入門 - 保護機制 (share) - 許貽昇](https://butternut-dinghy-bc9.notion.site/PWN-share-9d1bca4f1ec7432ea7d924f502dd658f)
( 關於 No eXecute-NX )
[PWN|入門 - x86/x64 Calling Convention (share) - 許貽昇](https://butternut-dinghy-bc9.notion.site/PWN-x86-x64-Calling-Convention-share-2a561c309e2e474e93a0f324fba9f9c0)
( 對,就是 calling convention )
[PWN|基礎 攻擊手法 1 (share) - 許貽昇](https://butternut-dinghy-bc9.notion.site/PWN-1-share-dd36626684024e4b85fc4118bd77f1d7)
( 簡單 ROP 說明 )
------------------------------------------
【ROP Emporium】Lab!!!!
[ROP Emporium](https://ropemporium.com/index.html)
( Lab 練習題來源 )
[栈溢出练习:ROP Emporium](https://www.kn0sky.com/?p=938527f1-03c4-4349-8110-5510f7d4b84a)
( writeup 參考 )
------------------------------------------
【大神的 Slides】
[ROP輕鬆談 - Lays(L4ys)](https://www.slideshare.net/slideshow/rop-40525248/40525248#45)
[Linux Binary Exploitation - Angelboy](https://www.slideshare.net/slideshow/binary-exploitation-ais3/79271260#106)
------------------------------------------
【ELF 檔案】仙貝知識!!!
[執行檔格式 - ELF](https://ithelp.ithome.com.tw/articles/10222650)