# Fixed Size Migration > Author: 堇姬Naup ## Why - 不能控制輸入長度時,就只能使用原本main function read 來多次輸入 ROP chain 假設現在空間只夠輸入一個gadget ``` payload (2*8 bytes) + rbp + return address(8bytes) ``` 觀察一下會發現 main_read 其實會將輸入存到 rbp-0x10,可以利用這個特性來寫入 ROP chain ``` read leave ret ``` leave ``` mov rsp rbp pop rbp ``` ## 原理 ``` 空間(8bytes) 空間(8bytes) old rbp return address(8bytes) ``` 然後有一塊可以寫ROP的地方`buf1` ``` *buf1 - 0x10 *buf1 - 0x08 *buf1 *buf1 + 0x8 *buf1 + 0x10 *buf + 0x18 *buf + 0x20 ``` 這裡我們構造 ``` aaaa(padding 0x10) buf1(old rbp) main_read ``` 第一次跑的時候,會在底下先遇到一個leave stack rbp指的地方會從 ``` aaaa(padding 0x10) buf1(old rbp)<-rbp main_read ``` 變成 ``` *buf1 - 0x10 *buf1 - 0x08 *buf1 <-rbp *buf1 + 0x8 *buf1 + 0x10 *buf + 0x18 *buf + 0x20 ``` 這時候ret會跳回main read 我們輸入gadget 1 、 gadget 2 、 buf2 、 main read(因為read會把東西存到rbp-0x10) ``` *buf1 - 0x10 gadget 1 *buf1 - 0x08 gadget 2 *buf1 <-rbp buf2 *buf1 + 0x8 main read *buf1 + 0x10 *buf1 + 0x18 *buf1 + 0x20 ``` 這時候read完會碰到leave,rsp會先指到rbp一樣的位置,然後pop rbp,rsp指到`*buf1 + 0x8`,而rbp指到`*buf2` ``` *buf1 - 0x10 gadget 1 *buf1 - 0x08 gadget 2 *buf1 buf2 *buf1 + 0x8 <-rsp main read *buf1 + 0x10 *buf1 + 0x18 *buf1 + 0x20 ``` ``` *buf2 - 0x10 *buf2 - 0x08 *buf2 <- rbp *buf2 + 0x8 ``` 再來ret,會ret到main read ``` *buf1 - 0x10 gadget 1 *buf1 - 0x08 gadget 2 *buf1 buf2 *buf1 + 0x8 main read *buf1 + 0x10 <-rsp *buf1 + 0x18 *buf1 + 0x20 ``` 寫到rbp-0x10,但我們目標都寫在buf1,所以這輪不寫,直接填充a ``` *buf2 - 0x10 aaaaa... *buf2 - 0x08 aaaaa... *buf2 <- rbp buf1 + 0x10 *buf2 + 0x8 main read ``` main read完leave,rsp指到rbp,rbp拿最上面的拿到buf1 + 0x10,指過去 ``` *buf1 - 0x10 gadget 1 *buf1 - 0x08 gadget 2 *buf1 buf2 *buf1 + 0x8 main read *buf1 + 0x10 <-rbp *buf1 + 0x18 *buf1 + 0x20 ``` ``` *buf2 - 0x10 aaaaa... *buf2 - 0x08 aaaaa... *buf2 <-rsp buf1 + 0x10 *buf2 + 0x8 main read ``` 再來ret到main read,寫入資料rbp-0x10(寫入gadget 3、gadget 4、buf2、main read) ``` *buf1 - 0x10 gadget 1 *buf1 - 0x08 gadget 2 *buf1 gadget 3 *buf1 + 0x8 gadget 4 *buf1 + 0x10 <-rbp buf2 *buf1 + 0x18 main read *buf1 + 0x20 ``` 遇到leave,rsp會先指到rbp一樣的位置,然後pop rbp ``` *buf2 - 0x10 aaaaa... *buf2 - 0x08 aaaaa... *buf2 <-rbp buf1 + 0x10 *buf2 + 0x8 main read ``` ``` *buf1 - 0x10 gadget 1 *buf1 - 0x08 gadget 2 *buf1 gadget 3 *buf1 + 0x8 gadget 4 *buf1 + 0x10 buf2, *buf1 + 0x18 <-rsp main read *buf1 + 0x20 ``` 之後ret到main ,輸入aaaa(padding 16 bytes),之後 buf1 - 0x18 ,leave ``` *buf2 - 0x10 aaaaa... *buf2 - 0x08 aaaaa... *buf2 <-rbp buf1 - 0x10 *buf2 + 0x8 leave ``` 先遇到一次leave,rsp會先指到rbp一樣的位置,然後pop rbp ``` *buf2 - 0x10 aaaaa... *buf2 - 0x08 aaaaa... *buf2 buf1 - 0x18 *buf2 + 0x8 <-rsp leave ``` ``` *buf1 - 0x18 <-rbp 隨便 *buf1 - 0x10 gadget 1 *buf1 - 0x08 gadget 2 *buf1 gadget 3 *buf1 + 0x8 gadget 4 *buf1 + 0x10 buf2, *buf1 + 0x18 main read *buf1 + 0x20 ``` ret到leave,再做一次leave,rsp會先指到rbp一樣的位置,然後pop rbp, ``` 隨便<-rbp ... *buf1 - 0x18 隨便 *buf1 - 0x10 <- rsp gadget 1 *buf1 - 0x08 gadget 2 *buf1 gadget 3 *buf1 + 0x8 gadget 4 *buf1 + 0x10 buf2, *buf1 + 0x18 main read *buf1 + 0x20 ``` 之後ret開始執行gadget,這樣就成功寫入gadget並執行了 https://www.youtube.com/watch?v=ogr66Mc-YOk
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up