萬盛學電腦網

 萬盛學電腦網 >> 健康知識 >> VISTA用戶內存安全保護漫談之safeseh

VISTA用戶內存安全保護漫談之safeseh

前言最近開始折騰VISTA,上個月在SST的BIOS沙龍SP2上講過一點自己研究的心得加上收集到的一點資料混合起來的東西。會後幾個朋友要資料,說實話,第一是vista在內存安全保護方面的改進是比較大的,涉及面比較廣,而VISTA的研究也是才剛剛開始,關於vista的研究資料也是非常的少,每個改進都需要自己慢慢的去分析對比和研究.第二就是vista的安全越來越需要安全環境特別是編譯器方面的配合,vista本身的庫代碼幾乎全部是用.net編譯器編譯的,我使用的.net 2003也缺乏一些vista下支持的安全特性(估計MS有新的針對vista的開發環境),而且以前對.net的研究幾乎沒有,現在才開始找些.net的書來補習。第三就是目前我的工作也比較繁雜,研究vista的安全保護機制只是因為某一項工作的需要,並非是這項工作的主題,而我這個人又比較懶散,覺得只是分析機制,缺乏新創意的東西懶得動筆寫。但是現在覺得好久沒有寫點東西出來了,又答應過一些朋友要發布的,想想還是慢慢湊一些東西出來吧,只是關於VISTA的研究是長期的工作,靠一人之力只能有一點研究就寫一點吧。所以學當年小四的學習筆記形式寫寫,因為當然其中錯誤與偏漏之處難免,只能姑稱之漫談。什麼是safeseh以前堆棧溢出在的WINDOWS系統中一直都是安全問題的核心,其中覆蓋seh的技術早為人熟知。safeseh是一項保護和檢測和防止堆棧中的seh被覆蓋而導致利用的技術。safeseh是vista的新技術嗎?safeseh並不是vista的新技術,safeseh是xp sp2就已經引入的技術。但是由於safeseh需要.net的編譯器編譯的image才支持,而xp sp2系統自身所帶的庫和執行程序都是非.net的編譯器編譯的,所以使得safeseh在xp sp2上只能成為聾子的耳朵,xp sp2下,堆棧溢出只要覆蓋seh的地址就能輕松饒過所有的保護機制。因此在xp sp2時代,關於safeseh的研究從來不被重視,甚至對他的機理研究都存在很多錯誤,認為safeseh只是屏蔽了數據段的地址,只要是庫函數空間地址就是被許可的,一些safeseh的操作被誤解讀成函數地址保護的操作。為什麼vista下safeseh才開始發威vista自身帶的系統庫。程序99%以上是用.net的編譯器編譯的,.net的編譯器默認編譯時候就會在IMAGE裡產生對safeseh的支持。因此vista下的應用加載的系統庫幾乎全是帶有safeseh支持的IMAGE,堆棧溢出發生時覆蓋這些支持safeseh模塊的SEH都能被檢查出來,使得覆蓋堆棧中的SEH地址的技術不再可用。safeseh的實現過程safeseh本身的原理很簡單,就是在編譯器生成二進制IMAGE的時候,把所有合法的SEH函數的地址解析出來,在IMAGE裡生成一張合法的SEH函數表,用於異常處理時候進行嚴格的匹配檢查。基本過程如下(XP SP2和VISTA一樣): 加載過程:加載IMAGE時,定位和讀出合法SEH函數表的地址(如果該IMAGE是不支持safeseh的,則這個SEH函數表的地址為0),使用shareuser內存中的一個隨機數加密。將加密的SEH函數表的加密地址,IMAGE的開始地址,IMAGE的長度,合法SEH函數的個數 作為一條記錄放入ntdll的加載模塊數據內存中。 異常處理過程:根據堆棧中SEH的地址,確認是否屬於一個IMAGE的地址空間。如果屬於讀取ntdll的加載模塊數據內存對應的“SEH函數表的加密地址,IMAGE的開始地址,IMAGE的長度,合法SEH函數的個數"記錄 讀出shareuser內存中的一個隨機數,解密SEH函數表的加密地址,讀出真實的SEH函數表地址如果該地址不為0,代表該IMAGE支持safeseh根據合法SEH函數的個數,依次計算合法合法SEH函數的地址並和當前SEH地址進行比較,如果符合執行SEH函數,如果全不符合則不執行當前SEH指定的地址,跳出不執行。如果該地址為0,代表該IMAGE不支持safeseh,,只要該內存屬於該IMAGE .code范圍內的代碼都可以執行如果不屬於檢測該地址的內存特征。一般屬於內核空間的未加載用戶數據地址可以執行(但是其實等效於無法執行的,這塊不可能加載用戶數據,可能是MS為了迷惑一些研究者吧,看見代碼能跳轉到如0xcccccccc地址上,以為能饒過safeseh.) vista下的safeseh的安全性safeseh是非常強悍的,如果一個進程加載的所有模塊都是支持safeseh的image,覆蓋seh獲得利用就根本不可能。至少VISTA下99%的系統庫是支持safeseh的image。而xp sp2 99%的系統庫是不支持safeseh的image,因此safeseh雖然是xp sp2就開始使用的技術,但應該算是在vista下才開始發揮作用的技術。當然如果進程存在一個不支持safeseh的IMAGE就等於整個safeseh的機制失效,不過由於vista下支持進程空間隨機技術,可以深層抵御這種情況下的seh覆蓋利用。當然一個思路是:是否可以通過覆蓋shareuser內存中的隨機數字和ntdll的SEH函數表的加密地址使得計算出來的SEH函數表的地址為0饒過safeseh的保護。不過這很困難:因為要達到這個目的除非存在下面的情況:情況A:知道shareuser內存中加密隨機數,並能修改SEH加密地址,則需要知道ntdll加載的地址(隨每次啟動不同),且能通過漏洞獲取shareuser內存中加密隨機數,通過計算獲得為0的加密地址再寫入到SEH加密地址中情況B:知道SEH加密地址的數值,並能修改shareuser內存中加密隨機數,則需要知道ntdll加載的地址(隨每次啟動不同),且能通過漏洞獲取SEH加密地址的數字,通過計算獲得為0的加密KEY,再寫入到shareuser內存中情況C:需要知道ntdll加載的地址,並能夠改寫修改SEH加密地址和shareuser內存中加密隨機數。以上3種情況都需要特定的復合條件,很難具備可能的問題依然存在著一些可能的問題.第一就是支持safeseh需要.net的編譯器支持,且程序所有加載的IMAGE都需要支持safeseh,否則容易導致失效,但依然有大量的第三方程序和庫不是使用.net編譯的第二就是我使用的.net 2003只對c 的windows應用的默認編譯中就支持safeseh安全特性,在.net的應用編譯中,對於運行時生成的托管代碼,即使打開安全選項也不會支持一些安全特性,不知道.net 2005或者MS是否有最新的支持vista的.net出來。

copyright © 萬盛學電腦網 all rights reserved