.prettyprint.linenums ol li, pre.prettyprint.linenums ol li { list-style: decimal; }

2017年9月6日 星期三

[學習] SROP學習紀錄

剛剛上篇講到SROP,這邊詳細紀錄下這個手法


這手法我比較少聽別人說到,雖然很多人都說比ROP好用很多


第一次出現是在2014年的IEEE security and privacy的conference上提出,還被評選為最佳學生paper


SROP全名叫sigreturn oriendted programming,跟ROP相比,只多了sig3個單字


ROP相信大家都知道是什麼鬼,基本上來說是現在exploit不可或缺的技術之一,所以後面簡單的解釋下signal


signal是一種IPC(inter-process communication)技術,主要用來發出訊息通知某process某事件已發生,這時候該process就會被OS中斷工作然後去處理signal。如果該process有寫明遇到某signal該做什麼動作(register a signal handler),則系統會乖乖去做,沒寫明就會以預設動作去執行。


當一個signal發起時,kernel會先把當前的一些狀態塞進stack裏面存好(registers的值之類的,這塊存放的空間稱為signal frame),再進到kernel space執行工作,當一切處理完時會經由sigreturn恢復process的狀態 (把存在stack frame提領出來),然後再繼續跑剛剛沒跑完的事情


主要流程如下:




這邊有幾點我們可控:1. signal fame放在stack中,stack通常可控 2. sigreturn也是種syscall,控的了return address就能呼叫sigreturn


所以利用方法很簡單,透過「夠大」的stack上放了你想存進register的值(擺放有一定的順序,不同架構不盡相同),最後呼叫sigreturn,就能把相對應的值擺進相對應的syscall裏面,只要在設定ip的地方擺上syscall位址,就能呼叫任意syscall


這邊我借一下別人的圖,看了應該就能懂:


當然因為sp bp都放在stack中,也可以透過更改這些register的值改變stack位址


在angelboy大大的slide上,也特別注明一些像是gs cs等segment register儘量不要去更動,以免出錯,同樣的ep sp也不可以填上0,不然一樣會錯


上一題的end中,我原本想透過讀306個bytes呼叫syncfs來把rax歸零,最後再讀入15個字元呼叫sigreturn然後偽造signal frame call execve,但是後來發現實在太難達成,因為要連控eip勢必得溢出296bytes,很難一邊溢出296bytes一邊拿出sigreturn,就算真的把esp改掉讓stack frame縮小,我還得知道之後的stack位置來放/bin/sh,總之就是很麻煩


不過這個思路實際上也是從一篇文章中學來的,很可惜沒有用到QQ


我目前對SROP的粗淺理解大概到這邊,更詳細的可以看angelboy大大的slide (大大好人一生平安QQ)

下面放上我參考過的Reference:

[1]x64-sigreturn-oriented-programming
[2]sigreturn_by_angleboy
[3]Sigreturn Oriented Programming (SROP) Attack攻击原理
[4]FramingSignals-AReturntoPortableShellcode
[5]srop-slides


沒有留言:

張貼留言