天天看點

write up --RCTF2017 Recho

RCTF2017的一題pwn題,之是以把這一題分享給大家是因為,這一題不像我們想象的那樣簡單,RCTF的品質還是很高的,接下來我們來看看這一題。

write up --RCTF2017 Recho

可以看到隻有一個棧不可執行的保護。

write up --RCTF2017 Recho

可以看到這一題的漏洞點是很明顯的,我剛開始想的是直接rop梭哈了,但是等我exp一半的時候,發現while裡的read函數的傳回值一直都是真,是以這個循環一直都是出不去的,那這不完犢子了嗎。

這該咋解啊,出題人這麼陰間的嗎?在Linux上我們可以直接Ctrl+D結束我們的輸入,但是我們打遠端這種情況就莫得辦法了呀。

然後就看了一些大佬的write up,發現pwntools裡面有個函數shutdown函數可以強行的去結束擷取輸入,這樣就可以結束這個循環了。

但是這樣結束的話就不能進行ROP了,那這樣我們還怎麼洩漏libc基址來攻擊呢?

這樣我們就得重新分析了,我們再來看一看IDA的反編譯代碼看看還有什麼可以利用。

溢出的漏洞已經有了

write up --RCTF2017 Recho

有上圖的這些函數可以用

write up --RCTF2017 Recho

可以看到data段有個flag,那麼也就是說,對應的遠端主機上有這麼一串flag隻要我們能讀取并輸出即可。

這兩個有用的資訊一結合,在使用之前我做到的一題存在沙箱的一題,我一下就明白了,大佬們的思想,使用orw來把flag輸出出來。

那你可能會問了這程式也沒調用過open函數啊,你咋用open打開flag文本呢?

小了,我隻能說小夥子你思考的範圍小了,老夫給你看一樣東西glibc源碼,看完你就懂了。

小夥子你看好了老夫隻教你一遍

write up --RCTF2017 Recho

這裡可以看到alarm加上5的地方就是64位的系統調用syscall的位址。

在我們學習系統調用的時候是不是學到過,把相應的系統調用号放到rax(eax)寄存器中,然後使用syscall來進行系統調用。

write up --RCTF2017 Recho

然後看着一段彙編代碼,先來了解一下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

write up --RCTF2017 Recho

我們來重新的捋一捋攻擊的過程

利用有用的資訊将alarm表裡的内容改為syscall的首部,進而實作調用alarm函數就是調用syscall。

利用open函數打開遠端主機的flag文本,然後使用read函數将flag的内容讀取到bss段的某個位置。

然後利用printf函數将這段内容輸出。

(當然我們還需要使用ROPgadget工具來找到可以被我們利用的pop rdi ,pop eax,pop rsi,pop rdx等等)

接下來就可以編寫exp了。

繼續閱讀