ADL CTF 2015 - SimpleEcho2

題目

這一題延續 project1 題目: SimpleEcho

改成本身實作 socket server 由 fork 出的 handler function echo

![](http://user-image.logdown.io/user/14835/blog/14031/post/369965/yKegIfCBTfCWkvsvAKkG_Q.jpg)

這題是 x64 的 binary, calling convention 有一些參數是放在 register 在 rop 時要特別注意

漏洞一樣是在 buffer 大小比 read 長度限制還小 這題有開各種保護

![](http://user-image.logdown.io/user/14835/blog/14031/post/369965/EHIWyt5HQjmyAVzfZHqL_Q2.jpg)

要進行ROP首先要能控制 ret adr, 再有 canary 保護之下控制 ret adr 要先能把 canary 蓋回去

拿 canary 的方式跟 SimpleEcho 一樣 先把 buffer 塞到 canary 的第一個 byte (經觀察都是 0 要避免截斷) 之後 echo 出來的內容就有 canary

過程

接下來還有一些要克服的問題

1\. 有開 PIE 要拿到 binary load base 必須先拿到相對 offset
  1. 題目 IO 是用 socket 連接 也就是 stdio 並沒有被 redirect to 我們建立的 socket
  2. payload 的長度還是受到 read size 的限制 (256)

第一點用 overflow echo 回 EchoServer 的 ret adr 便可以算出 loading base

能 overflow 到的地方都沒有 libc 相關的 address, 只好透過讀 got 拿 libc base 出來。

拿的方法是用 rop ret to sendMsg, socket fd 在 stack overflow 的到的地方,把 got 內容 send 回來

因為 service 是 fork 出來的 所以每次連 libc, loading base 都會固定,所以我由 exit ret to ROP chain 拿到 base adr 後直接 reconnect

接著我原本想直接 ret to system, 或 rop syscall execv 甚至真的把 payload 都寫出來了,但 shell 只能開在 host 上,原因便是上面第二點

這邊我打算 got hiject strlen 讓 host 收到 input 直接當 cmd 跑

理論上直接寫入 got 就 OK 但我寫入時一直 Seg fault, 看一下 maps 竟然沒有 write

![](http://user-image.logdown.io/user/14835/blog/14031/post/369965/8zud3K3RRAHMZSLO4Ncw_G3.jpg)

只好先 rop mprotect 修改,再 hiject 這過程又會碰上第三點的問題 只好第一段 payload 最後先 ret 回 EchoServer 再送第二段

完整 pwn python script

https://gist.github.com/leepupu/338503f2465a7c28c54e