標籤:style blog http io color ar 使用 for sp
微軟在堆中也增加了一些安全校正操作,使得原本是不容易的堆溢出變得困難重重:
* PEB Random:在 Windows XP SP2 之後,微軟不再使用固定的 PEB 基址 0x7FFDF000,而是使用具有一定隨機性的基址,從而影響了 DWORD SHOOT 對 PEB 中函數的攻擊。
* Safe Unlink:微軟改寫了操作雙向鏈表的代碼,在卸載 free list 中的堆塊時更加小心。SP2 在進行刪除操作時,提前驗證堆塊的完整性,以防止 DWORD SHOOT:
1 int safe_remove(ListNode * node) 2 { 3 if( (node->blink->flink==node)&&(node->flink->blink==node) ) 4 { 5 node -> blink -> flink = node -> flink; 6 node -> flink -> blink = node -> blink; 7 return 1; 8 } else { 9 // raise exception10 return 0;11 }12 }
* Heap Cookie:與棧中類似,堆中也引入了 cookie,用於檢測堆溢出的發生。cookie 布置在堆首中原堆塊的 segment table 的位置,占 1 位元組:
* 中繼資料加密:Windows Vista 及後續版本的系統中開始使用這項措施。塊首中的一些重要資料在儲存時會與一個 4 位元組的隨機數進行異或加密,使用時再異或解密。這樣就不能直接破壞這些資料了。
堆的研究者之一 Matt Conover 在 CanSecWest 04 的演講議題 Windows Heap Exploitation (Win2K SP0 through WinXP SP2) 中,針對 PEB random 機制,指出變動只是在 0x7FFDF000 ~ 0x7FFD4000 之間,隨機區間不大,在多線程狀態下容易被預測出來。
而 Heap Cookie 只佔 1 位元組,在研究其產生隨機的演算法之後仍存在破解可能。
對於 Safe Unlink 也有人找到了一些破解思路。
但這些突破的思路要在 XP SP2 之後成功實施並利用,需要十分苛刻的條件,堆溢出變得難如登天。
溢出堆中的資料
但堆保護措施是對堆的各個關鍵資料結構進行保護,對堆中的資料不提供保護,所以攻擊的第一個思路,是溢出堆中存放的關鍵資料結構:重要變數、資料、函數指標…
利用 chunk 調整大小攻擊堆
Safe Unlink 是從 FreeList[n] 上拆卸 chunk 時對雙向鏈表進行驗證,但是,將一個 chunk 插入到 FreeList[n] 時沒有進行校正!如果能偽造一個 chunk 並將其插入到 FreeList[n] 上就可以造成某種攻擊。如下兩種情況會發生插入操作:
1 記憶體釋放後 chunk 不再被使用時。2 當 chunk 的記憶體空間大於申請的大小,剩餘的空間會被建成一個新的 chunk 鏈入鏈表中。
上述第二種情況提供了可以利用的機會。先考慮申請 chunk 的過程,從 FreeList[] 上申請空間的過程如下:
1 將 FreeList[0] 上最後一個 chunk 與申請的大小進行比較,如果 chunk 的大小 ≥ 申請的大小,則繼續指派,否則擴充空間(若超大堆塊鏈表無法滿足分配,則擴充堆)2 從 FreeList[0] 的第一個 chunk 依次檢測,直到找到第一個符合要求的 chunk,然後卸載3 分配好空間後,如果 chunk 有剩餘空間,剩餘空間會建成新的 chunk 並插入到鏈表中
這個過程中,第一各情況沒有機會,第二種情況有 Safe Unlink 進行保護。但 Safe Unlink 存在一個問題:即使 Safe Unlink 檢測到 chunk 結構被破壞,還是會允許後續的一些操作,如重設 chunk 大小。
OD: Protection for Heap in Windows