Stack migration(pivoting)
Author: 堇姬Naup
概念
- 可輸入的 ROPchain 長度不夠時,可以擴展輸入的方法,將 ROPchain 分好幾次寫在指定的區域,最後再將 stack 移動過去執行
- 如果找到其他地方有足夠空間放ROP,就可以用較少的gadget數,來將stack搬移至ROP位置,進行ROP
leave
實際上做了兩件事
1 | mov rsp, rbp |
方法
leave;ret
- 透過overflow將rbp填成ROP Chain開始位置address-8
- return address填入leave;ret 的gadget
有一塊可以寫ROP gadget的地方
1 | *0x601090(這塊記憶體開始的位置) |
stack狀態
1 | *0x10210<-rsp |
填入payload
1 | *0x10210<-rsp |
首先一路執行下來
通常最後會有個
leave;ret
而leave的意思是
1 | mov rsp, rbp |
所以rsp會變成rbp
1 | AAAAAAAA |
之後pop rbp會讓stack第一個值推入rbp,也就是0x601090
所以rbp會指向那塊記憶體
1 | *0x601090 <- rbp |
之後ret,rsp往下指到leave;ret gadget前面
1 | AAAAAAAA |
接下來rsp繼續往下
在吃到一次leave,rsp會變成rbp,
1 | *0x601090 <- rbp,rsp |
再來pop rbp,rbp指到遙遠的地方0xdeadbeef(總之就是設成這個值)
最後ret,rsp往下指
1 | *0x601090 |
這樣就會開始執行ROP gadget了
題目
checksec
開NX不能寫shellcode
然後其實沒開canary
source code
1 |
|
首先name這塊區域夠大了,應該可以寫ROPgadget,另外s的部份太小了,要用stack migration來改rsp的位置
另外最後有leave
- execve(‘/bin/sh’)
暫存器 | 值 |
---|---|
rax | 0x3b |
rdi | 要執行的參數值(/bin/sh) |
rsi | argv(這裡=0) |
rdx | envp(這裡=0) |
gadget | address |
---|---|
pop rax ; ret | 0x4516c7 |
pop rdi ; ret | 0x40186a |
pop rsi ; ret | 0x40f40e |
pop rdx ; ret | 0x40176f |
leave ; ret | 0x401dd0 |
syscall | 0x4012d3 |
新rsp address->0x4c3300
name
1 | *0x4c3300 |
s
1 | 'A'*0x10 |
這樣就可以讓rsp移到一塊大的記憶體來放ROPgadget,另外把也把/bin/sh放到這塊記憶體開頭這樣就可以抓到了
(可以按照上面的邏輯自己推一遍)
script
1 | from pwn import * |
getshell!!!