我們將Stack buffer overflow和Reverse的內容大概介紹完了,其實還有很多,比如Return to libc、Heap overflow、格式化字串、ROP或繞過一些保護手法等等的內容,底層的東西要學的有很多,但概念會了後,大概都能猜出可能可以從哪裡下手或是列出可能的方法去嘗試,但已經到鐵人賽的尾聲了,要介紹完全部不太可能,因此最後來介紹一下簡單的ROP。
ROP 是利用現有程式碼段,稱為 Gadgets,來達到任意程式碼執行,這種技術特別有效於繞過某些安全機制,如 NX等,當記憶體區域被標記為不可執行,例如 NX啟用時,傳統的 Shellcode 無法直接執行,ROP 通過重新組合現有的程式碼片段來執行攻擊。
正常來說,一個程式不太會去call system("/bin/sh")這種東西,但如果有用system這個Function,那我們就可以利用Return to libc來攻擊,但如果都沒有的話,我們就要利用ROP來進行攻擊。
在程式運作中,一定會有一些零星的小程式(Gadgets)來幫助主程式,比如將EAX POP掉後就Return這種迷你程式,而正就是因為有這些Gadgets的幫助,我們就可以來構造自己想要的程式碼,聰明的你如果想到之前說過的System call就已經知道解答了,在我們之前利用shellcraft生成的Shellcode不就是放好對應的暫存器參數EAX、EBX、ECX和EDX然後int 0x80就可以利用System call拿到Shell了嗎!
我們這個時候就可以利用ROPgadget來幫助我們看程式當中有哪些Gadget,選的範例是出自於ctf.hackme.quest的ROP這題,這邊已經用checksec檢查過,是只有開啟NX保護的,接著我們下ROPgadget --binary rop。
ROPgadget會顯示出全部我們可能可以利用到的Gadgets,我們這個時候可以看到System call table (也可以下指令看man system),以32位元的Linux系統來說,EAX放0xb,EBX放/bin/sh,ECX和EDX放0,最後找到int 0x80就可以做System call的execve執行/bin/sh拿到Shell了。
所以我們來看ROP這支程式有哪個Gadget是POP EAX然後就ret的,可以看到是0x80b8016。
POP EBX、ECX和EDX也有了。
還有最重要的int 0x80。
但這邊會遇到一些問題,比如說EBX的/bin/sh字串要寫在哪,這個部分我們可以來找有哪些是pop dword ptr的Gadget,這邊可以看到0x804b5ba很單純,POP ECX當中的字串就Return了,那我們就可以利用它,先跳到0x804b5ba後面接參數就可以了,但因為一個暫存只能放4 Bytes,所以我們要寫/bin/sh的話要分兩次寫。
還有一個問題是我們該寫在哪呢,這個時候就要看proc中的maps了,路徑是/proc/pid/maps,pid可以下ps指令來得知process的pid,可以知道0x80e9000開始可以寫入。
這個時候就可以開始寫Code了,這邊已經用cyclic算好Padding是16,要注意的是在做設定 EAX 時,寫法會是pwn.p32(0x80b8016)+pwn.p32(0xb),先放要Return過去的 Address 再放那個Function需要的參數依此類推,因為跳過去後 ESP 往下跑,將值 POP 出去會從ESP指向的Address 去做POP,也就是將下一個放的值 POP 出去,因此要先放Gadget再放參數。
寫完的Code會長這樣,在做 ECX 寫入時,會先跳進POP ECX的Gadget,執行POP ECX,把ESP上的可寫入Address帶入ECX中,再來是pop dword ptr 到ECX,帶的參數是"/bin"的 Bytes 格式,我們就把/bin透過ECX送到write內了。
第二個送入/sh也是一樣,要注意的點是這次送的位置是write+4,因為write+0已經放了/bin,不能將它覆蓋掉,還有/sh後面要加\0將它補齊,\0的意思是空字符,最後用int 0x80結束整個ROP chain。
這樣就拿到Shell權限了!
而ROPgadget有個更方便的功能,叫做ropchain,如果我們下ROPgadget --binary rop --ropchain後,最下面會直接顯示可用的Code。
將ROPgadget的程式修改成pwntools的格式後,再加上我們算出的Padding以及在最後做interactive交互。
這樣就能夠成功拿到Shell了!
但ROPgadget的ropchain功能並不是每個ROP題型都能做,所以還是建議大家了解ROP原理後自己嘗試寫一個Payload才能真的學到東西,而這些題目也有許多變化,例如我可以用0x806ecd9連續POP EBX和EDX,只要後面也按照順序放入Stack當中也能做到,所以不是只有POP完做ret的才能用,只要Gadget能夠達成目的的都可以使用。
所以如果將Payload改成這樣,也是可以達到目的,ROP的變化很多,沒有固定答案,有發現好玩的Gadget都能夠使用,儘量靈活的使用這些Gadgets吧!