RCTF2017的一題pwn題,之是以把這一題分享給大家是因為,這一題不像我們想象的那樣簡單,RCTF的品質還是很高的,接下來我們來看看這一題。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SOzEDMmVzYjRmZ3cTY1YTN2MWNwETYmhzMlNjMzkTMi9CX2IzLclDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL4M3Lc9CX6MHc0RHaiojIsJye.png)
可以看到隻有一個棧不可執行的保護。
可以看到這一題的漏洞點是很明顯的,我剛開始想的是直接rop梭哈了,但是等我exp一半的時候,發現while裡的read函數的傳回值一直都是真,是以這個循環一直都是出不去的,那這不完犢子了嗎。
這該咋解啊,出題人這麼陰間的嗎?在Linux上我們可以直接Ctrl+D結束我們的輸入,但是我們打遠端這種情況就莫得辦法了呀。
然後就看了一些大佬的write up,發現pwntools裡面有個函數shutdown函數可以強行的去結束擷取輸入,這樣就可以結束這個循環了。
但是這樣結束的話就不能進行ROP了,那這樣我們還怎麼洩漏libc基址來攻擊呢?
這樣我們就得重新分析了,我們再來看一看IDA的反編譯代碼看看還有什麼可以利用。
溢出的漏洞已經有了
有上圖的這些函數可以用
可以看到data段有個flag,那麼也就是說,對應的遠端主機上有這麼一串flag隻要我們能讀取并輸出即可。
這兩個有用的資訊一結合,在使用之前我做到的一題存在沙箱的一題,我一下就明白了,大佬們的思想,使用orw來把flag輸出出來。
那你可能會問了這程式也沒調用過open函數啊,你咋用open打開flag文本呢?
小了,我隻能說小夥子你思考的範圍小了,老夫給你看一樣東西glibc源碼,看完你就懂了。
小夥子你看好了老夫隻教你一遍
這裡可以看到alarm加上5的地方就是64位的系統調用syscall的位址。
在我們學習系統調用的時候是不是學到過,把相應的系統調用号放到rax(eax)寄存器中,然後使用syscall來進行系統調用。
然後看着一段彙編代碼,先來了解一下al寄存器,首先在x86系統下的通用寄存器中有一個eax一般是用來儲存傳回值的,eax的低十六位是ax寄存器,而ax又分為高八位和低八位,而al寄存器正好是ax寄存器的低八位。
如果rdi寄存器中存的是alarm的got表,那利用這段彙編代碼,使rdi裡的位址再加上5,那rdi裡的位址不就是syscall的首部了嗎?
那這樣我們調用alarm函數是不是就相當于是調用syscall
這樣我們就有了syscall,那我們在找一個pop eax(rax)不就能想用什麼系統調用自己就能實作什麼系統調用了嗎。
這樣缺少open函數的問題就解決了,那麼就可以使用orw來讀取對應的遠端主機的flag,然後将flag輸出出來了。
那麼我們打開flag文本進行讀取,該讀到什麼地方呢?
我們可以讀到bss段啊對吧,bss段也是可讀可寫的段,這樣一來,我們就可以使用open打開flag的文本,把其中的内容read到bss段的某處,然後利用printf函數将flag裡的内容輸出出來。
可用的bss
我們來重新的捋一捋攻擊的過程
利用有用的資訊将alarm表裡的内容改為syscall的首部,進而實作調用alarm函數就是調用syscall。
利用open函數打開遠端主機的flag文本,然後使用read函數将flag的内容讀取到bss段的某個位置。
然後利用printf函數将這段内容輸出。
(當然我們還需要使用ROPgadget工具來找到可以被我們利用的pop rdi ,pop eax,pop rsi,pop rdx等等)
接下來就可以編寫exp了。