各種保護機制繞過手法
一.繞過GS編譯選項
●原理:通過VC++編譯器在函數前后添加額外的處理代碼,前部分用於由偽隨機數生成的cookie並放入.data節段,當本地變量初始化,就會向棧中插入cookie,它位於局部變量和返回地址之間
●繞過方法:
1.猜測/計算cookie
Reducing the Effective Entropy of GS Cookies:http://www.uninformed.org/?v=7&a=2&t=html
至從覆蓋SEH的方法出現后,這種方法目前已基本不用了,它沒有后面的方法來得簡便
2.覆蓋SEH
由於當security_check_cookie()函數檢測到cookie被更改后,會檢查是否安裝了安全處理例程,也就是SEH節點中保存的指針,如果沒有,那么由系統的異常處理器接管,因此我們可以通過(pop pop ret)覆蓋SEH來達到溢出的目的。但對於受SafeSEH保護的模塊,就可能會導致exploit失效,關於它的繞過在后續部分再述
輔助工具:OD插件safeSEH、pattern_create、pattern_offset、msfpescan、memdump
3.覆蓋虛表指針
堆棧布局:[局部變量][cookie][入棧寄存器][返回地址][參數][虛表指針]
當把虛表指針覆蓋后,由於要執行虛函數得通過虛表指針來搜索,即可借此劫持eip
4.利用未被保護的內存突破
5.替換.data中的Cookie突破GS
二.SafeSEH
●原理:
為了防止SEH節點被攻擊者惡意利用,微軟在.net編譯器中加入/sdeseh編譯選項引入SafeSEH技術。編譯器在編譯時將PE文件所有合法的異常處理例程的地址解析出來制成一張表,放在PE文件的數據塊(LQAJ)一C0N—FIG)中,並使用shareuser內存中的一個隨機數加密,用於匹配檢查。
如果該PE文件不支持safesEH,則表的地址為0。當PE文件被系統加載后,表中的內容被加密保存到ntdl1.dll模塊的某個數據區。在PE文件行期間,如果發生異常需要調用異常處理例程,系統會逐個檢查該例程在表中是否有記錄:如果沒有則說明該例程非法,進而不執行該異常例程
●繞過方法:
1.利用沒有啟動SafeSEH保護的模塊(比如漏洞軟件本身自帶的dll文件,可以借助OD插件SafeSEH來查看進程中各模塊是否開啟SafeSEH保護)
2.攻擊沒有開啟GS的函數
3.覆蓋虛表指針
4.利用堆繞過
5.利用某些ActiveX控件繞過
三.DEP繞過(數據執行保護)
●繞過方式:
1.某些程序沒有啟動DEP保護
2.Ret2Libc(最后可以執行ZwSetInfomationProcess,VirtualProtect,VitualAlloc)(ROP)
3.某些可以執行的內存(比如,Java Applet中動態申請中動態申請的內存空間具有可執行屬性)
4.利用某些.Net控件和Java控件來繞過
5.利用TEB突破DEP(局限於XP SP2以下的版本)
6.利用WPN與ROP技術
ROP(Return Oriented Programming):連續調用程序代碼本身的內存地址,以逐步地創建一連串欲執行的指令序列.WPM(Write Process Memory):利用微軟在kernel32.dll中定義的函數比如:WriteProcess Memory函數可將數據寫入到指定進程的內存中。但整個內存區域必須是可訪問的,否則將操作失敗
7.利用SEH繞過DEP
啟用DEP后,就不能使用pop pop ret地址了,而應采用pop reg/pop reg/pop esp/ret 指令的地址,指令 pop esp 可以改變堆棧指針,ret將執行流轉移到nseh 中的地址上(用關閉NX 例程的地址覆蓋nseh,用指向pop/pop /pop esp/ret 指令的指針覆蓋異常處理器)
四.ASLR繞過(地址隨機化)
●繞過方式:
1.基地址泄露漏洞,某個dll模塊的某個內存地址的泄露,進而可以泄露該DLL的基地址,進而可以得到任意DLL的基地址
2.某些沒有開啟地址隨機化的模塊
當瀏覽器加載一個帶try location.href = ‘ms-help://’ 語句的頁面時,HXDS.DLL就會被加載,而該DLL並沒有開啟地址隨機化
利用該方法的CVE-2013-3893, CVE2013-1347, CVE-2012-4969, CVE-2012-4792
3.堆噴射需要配合沒有開啟地址隨機化的模塊
4.覆蓋部分返回地址
雖然模塊加載基地址發生變化,但是各模塊的入口點地址的低字節不變,只有高位變化
對於地址0×12345678,其中5678部分是固定的,如果存在緩沖區溢出,可以通過memcpy對后兩個字節進行覆蓋,可以將其設置為0×12340000 ~ 0x1234FFFF中的任意一個值。
如果通過strcpy進行覆蓋,因為strcpy會復制末尾的結束符0×00,那么可以將0×12345678覆蓋為0×12345600,或者0×12340001 ~ 0x123400FF。
部分返回地址覆蓋,可以使得覆蓋后的地址相對於基地址的距離是固定的,可以從基地址附近找可以利用的跳轉指令。
這種方法的通用性不是很強,因為覆蓋返回地址時棧上的Cookie會被破壞。不過具體問題具體分析,為了繞過操作系統的安全保護機制需要考慮各種各樣的情況。
5.java Applet Spray:Java Applet中動態申請中動態申請的內存空間具有可執行屬性,可在固定地址上分配滑板指令(如Nop和ShellCode),然后挑轉到上面地址執行。和常規的HeapSpray不同,Applet申請空間的上限為100MB,而常規的HeapSpray可以達到1GB
6.just in Time Compliation(JIT)即時編譯,也就是解釋器(如python解釋器),主要思想是將ActionScript代碼進行大量xor操作,然后編譯成字節碼,並且多次更新到Flash VM,這樣它會建立很多帶有惡意xor操作的內存塊vary=(0×11223344^0×44332211^0×4433221);
正常情況下被解釋器解釋為:
如果非常規的跳轉到中間某一個字節開始執行代碼,結果就是另一番景象了:
關於JIT的詳細介紹,可以參考
●Pointer Inference and JIT Spraying以及
●Writing JIT-Spray shellcodefor fun and profit
●Pointer Inference and JIT Spraying
●Writing JIT-Spray shellcode for fun and profit
7.某些固定的基地址
★從Windows NT 4到Windows 8,
(1)SharedUserData的位置一直固定在地址0x7ffe0000上
(2)0x7ffe0300總是指向KiFastSystemCall
(3)反匯編NtUserLockWorkStation函數,發現其就是通過7ffe0300進入內核的
利用方法:
這樣,在觸發漏洞前合理布局寄存器內容,用函數在系統服務(SSDT / Shadow SSDT)中服務號填充EAX寄存器,然后讓EIP跳轉到對應的地方去執行,就可以調用指定的函數了。但是也存在很大的局限性:僅僅工作於x86 Windows上;幾乎無法調用有參數的函數
★64位Windows系統上0x7ffe0350總是指向函數ntdll!LdrHotPatchRoutine
(經過驗證可能不是這個地址,但是這個地址在開啟了ASLR后是固定的)
利用方法:
在觸發漏洞前合理布局寄存器內容,合理填充HotPatchBuffer 結構體的內容,然后調用LdrHotPatchRoutine。
(1)如果是網頁掛馬,可以指定從遠程地址加載一個DLL文件;
(2)如果已經經過其他方法把DLL打包發送給受害者,執行本地加載DLL即可。
此方法通常需要HeapSpray協助布局內存數據;且需要文件共享服務器存放惡意DLL;只工作於64位系統上的32位應用程序;不適用於Windows 8
五.SEHOP(Structured Exception Handling Overwrite Protection)
●原理:
它可作為SEH的擴展,用於檢 測SEH是否被覆寫。SEHOP的核心特性是用於檢測程序棧中的所有SEH結構鏈表的完整性,特別是對最后一個SHE結構的檢測。在最后一個SEH結構中 擁有一個特殊的異常處理函數指針,指向一個位於ntdll中的函數ntdll!FinalExceptHandler()。當我們用 jmp 06 pop pop ret 來覆蓋SEH結構后,由於SEH結構鏈表的完整性遭到破壞,SEHOP就能檢測到異常從而阻止shellcode 的運行
●繞過方式:
1.攻擊虛函數
2.攻擊未開啟SEHOP的模塊
3.攻擊沒有開啟GS的函數返回值
4.偽造SEH鏈表
六.堆保護
●原理:
(1)SafeUnlink:微軟改寫了操作雙向鏈表的代碼,在卸載free list中的堆塊時更加小心
(2)Heap cookie:用於檢測堆溢出
(3)元數據加密:微軟在Vista以及后續版本中使用了該安全措施,塊首中的一些重要數據在保存時,會與一個4字節的隨機數進行異或,在使用這些數
據的時候需要異或還原,這樣就不能直接破壞這些數據了,以達到保護堆的目的
●繞過方式:
(1)攻擊堆中的存儲變量
(2)利用chunk重設大小攻擊堆
(3)利用Lookaside表進行堆溢出
七.某些邏輯漏洞
●繞過方式:
1.Java的jnlp
是java提供的一種可以通過瀏覽器直接執行java應用程序的途徑,它使你可以直接通過一個網頁上的url連接打開一個java應用程序。
這種邏輯漏洞可以繞過EMET
2.微軟的Microsoft Silverlight,類似於java的jnlp,可以繞過上面的保護方式
3.某些VBScript可以繞過EMET(可以遠程調用一些文件)