IE漏洞攻防編年簡史

jopen 8年前發布 | 20K 次閱讀 IE

IE漏洞攻防編年簡史

本文對歷史上的微軟 IE 瀏覽器的影響較大 0day 做了梳理,討論了 IE 漏洞在攻擊防御技術上的進化,以及記錄了此類漏洞前人們在歷史上遺留下來的對抗經驗和足跡。

在 IE 瀏覽器攻防已經白熱化的進入到第三個階段的時候筆者才進入到 IE 瀏覽器攻防方面的研究學習。此時代號’Project Spartan’的微軟的 Edge 瀏覽器從 IE11 手中接過 windows 默認瀏覽器的重擔,使得服役將近 20 年的 IE 瀏覽器定格 11 這個歷史的大版本號上面,自覺對 IE 瀏覽器漏洞的歷史研究應有一篇簡記,可供后來的初入行的安全研究者有所參考,故成此文,疏漏之處再所難免,敬請指正。

0×01 瀏覽器漏洞研究的前置背景

最近幾年,網絡安全研究的部分重心開始有由 PC 端向移動端傾斜的趨勢。但是在 PC 端的安全研究依然以瀏覽器 IE/Chrome/Firefox/Spartan,Adobe 的 Reader/Acrobat/Flash 系列作為技術研究深度的展現。當然還有部分用于特定地區定向攻擊的文件格式漏洞也屬于一些黑客著重關注的領域,比如日本比較流行的字處理軟件 ichiaro 和在韓國地區比較流行的 Hancom Office 等字處理軟件系統以及 WPS 等字處理軟件方面的文件格式漏洞。

瀏覽器從誕生之初主要提供簡單的文檔閱讀功能.很少構成網絡安全威脅,但隨著互聯網的高速發展,越來越多的功能集被加入到瀏覽器中。瀏覽器不僅需要像操作系統那樣,為閱讀文檔、觀看電影、欣賞音樂等傳統計算機應用提供基礎,也需要為社交網絡、網絡購物等新興互聯網應用提供支持。瀏覽器在增加功能集的同時,也就帶來了更多的安全問題。而集成捆綁于系統中的 IE 瀏覽器可以占據市場較大份額,自然也成了眾矢之的。針對 IE 瀏覽器的攻防軍備競賽也就是在這種情況下拉開了帷幕。

0×02 IE 瀏覽器漏洞攻防的幾個時代

1. 1 緩沖區溢出和 ActiveX 控件時代(03 年-08 年)

03 年-08 年這是一個階段,這個階段時候的 IE 漏洞基本是以 ActiveX 控件造成的漏洞居多以及棧溢出漏洞還有一些簡單的堆溢出漏洞。比如 IFRAME 標簽的單個超長 SRC 屬性導致的緩沖區溢出以及類似的棧溢出漏洞。

早一些的階段,常規的 Fuzz 方法,無論是基于變形的還是基于生成的,比較適合應用于二進制格式的流數據,特別是那些包含大量 C 語言結構類型的文件或網絡協議格式。由于格式解析代碼經常不加檢查的使用數據流數據作為內存操作的參數,單點的畸形往往就足以觸發解析代碼中可能存在的處理漏洞:超長數據導致的緩沖區溢出、畸形數值導致的整數上溢和下溢、畸形索引值導致數組的越界訪問、畸形記數導致過量的內存讀寫操作。其中對于超長數據導致的緩沖區溢出,樣本構造起來相對簡單,傳入超長的值。所以這種類型的漏洞由于發掘起來相對簡單。

對早期的 IE 0day 漏洞的歷史簡單做一下梳理,只包含了影響比較大的例子(圖 1.1.1,圖 1.1.2),有些漏洞可能并不是 IE 本身的問題,但是以 IE 為最主要的利用渠道。

IE漏洞攻防編年簡史

圖 1.1.1

IE漏洞攻防編年簡史

圖 1.1.2

1. 2 時代關鍵字

防護方: DEP /ASLR / Stack Cookie

攻擊方: 棧溢出/簡單堆溢出/ROP/HeapSpray

A 緩沖區溢出

關于緩沖區溢出也簡單給出一個例子方便理解:

IE漏洞攻防編年簡史

圖 1.2.1

我們在 VC6.0 的編譯器編譯上述程序,執行后結果如下:

IE漏洞攻防編年簡史

圖 1.2.2

可以看到 main 函數中只調用了 foo 這個函數。但是實際運行中,bar 函數也被調用了。

實際上因為 foo 函數處理不當,并且外部輸入超長,造成了緩沖區溢出后修改了 foo ()函數的返回地址從而導致程序執行本不應該執行的 bar ()函數。而如果被覆蓋的返回地址是一串經過精心編碼具有后門功能的 shellcode,此時計算機即可被惡意攻擊者控制。

這只是一個簡單的C程序的范例,表現在瀏覽器當中形式上多少有所不同,比方說 IE 瀏覽器支持的 IFRAME 標簽,IFRAME 標簽的單個超長 SRC 屬性構造超長數據可能就會導致的緩沖區溢出從而瀏覽器崩潰。

DEP 和 Security Cookie

從上面的緩沖區溢出我們可以看到,在特定的環境下只要控制輸入的數據超長然后覆蓋掉返回地址,只要此時程序崩潰就很容易感知目標程序存在緩沖區溢出漏洞。然后在修改這串超長數據糅合上恰當的 shellcode 精確覆蓋返回地址就可以執行我們的惡意代碼。只是留給攻擊者的這樣的大好時光極為短暫。微軟從 Windows XP SP2 開始提供 DEP 的支持。DEP 全稱是 Data Execution Prevention,可以分為硬件的 DEP 和軟件的 DEP。但是目的都是一致的。阻止數據頁上代碼執行。(圖 1.2.3)

IE漏洞攻防編年簡史

圖 1.2.3

由于數據所在的內存頁被標識為不可執行,即使程序溢出成功轉入 shellcode 的執行,這個時候 CPU 就會拋出異常從而阻止惡意 shellcode 的執行。

從這里也可以看到這一階段的攻擊者只是去覆蓋棧上的返回地址,試圖從棧上將惡意 shellcode 執行起來。

考慮到攻擊是因為覆蓋返回地址產生的,微軟在 VS2008 和之后的編譯器加入了一個編譯選項 GS。也就是 Security Cookie 也可以稱為 Stack Cookie。

IE漏洞攻防編年簡史

圖 1.2.4

可以看到在開始的時候會將一個 security_cookie 提前寫入到棧中。而在函數返回之前會檢查這個 security_cookie 是否被篡改。

IE漏洞攻防編年簡史

圖 1.2.5

一旦被篡改便會跳轉到異常執行的流程:

IE漏洞攻防編年簡史

(圖 1.2.6)

當然這里說的是棧中的情況。在堆溢出中也有相似的防護措施如 Header Cookie。

盯上 SEH

當攻擊者發現覆蓋 4 字節返回地址(32 位系統)去執行 shellcode 這種攻擊方法的門檻被抬高之后便又想出了新的方案。覆蓋 SEH 的 Exception handler

其實在二進制的攻防當中所有的努力都是為了獲得哪怕一次控制 EIP (RIP)的機會。而 SEH 恰好符合這個要求可以給攻擊者提供這個機會。SEH 存放在棧內,故超長的數據就可能覆蓋掉 SEH  ,其中將異常處理函數的入口地址更改為 shellcode 的起始地址。由于溢出后產生的錯誤數據往往會觸發異常,而此時 shellcode 恰好可以得到一次被 EIP 指向的機會。

只是留給攻擊者的好時光依然極為短暫。在 VS2003(.net)當中支持了/SafeSEH 的選項,用于應對針對 S E H 的攻擊。后來又進一步推出了 SEHOP。當然這些措施需要 XP SP2 操作系統以及更新的操作系統還有 DEP 的配合。這兩種防護措施詳細展開又要占很多篇幅。感興趣的讀者可以自行學習。

需要說明的是 64 位的 windows 系統 SEH 已經不是放在棧中了。想要通過棧溢出覆蓋異常處理例程來實現漏洞利用已經是不可能的了。

ROP ASLR 和 HeapSpray 技術

前面說到 DEP 技術即使返回地址被 shellcode 覆蓋,DEP 也會去阻止 shellcode 的執行。但是如果執行的代碼是操作系統的庫本身提供的函數如直接使用 libc 庫中提供的 system ()函數來覆蓋程序函數調用的返回地址。然后傳遞重新設定好的參數使其能夠按照預期執行。這種繞過 DEP 的攻擊方式稱為 return to libc。

Return-to-libc 攻擊用庫函數的地址來覆蓋程序函數調用的返回地址,這樣在程序返回時就可以調用庫函數從而使攻擊得以成功實施。但是由于攻擊者可用的指令序列只能為應用程序中已存在的函數,所以這種攻擊方式的攻擊能力有限。并且攻擊只能在 x86 的 CPU 平臺中實施而對 x86_64 的 CPU 平臺中無效。這是因為 x86_64CPU 平臺中程序執行時參數不是通過棧傳遞的而是通過寄存器,而 return-into-libc 需要將參數通過棧來傳遞。

由于這種 return-to-libc 攻擊方式的局限性,返回導向編程(Return-Oriented Programming, ROP)被提出,并成為一種有效的 return-to-libc 攻擊手段。返回導向編程攻擊的方式不再局限于將漏洞程序的控制流跳轉到庫函數中,而是可以利用程序和庫函數中識別并選取的一組指令序列。攻擊者將這些指令序列串連起來,形成攻擊所需要的 shellcode 來從事后續的攻擊行為。因此這種方式仍然不需要注入新的指令到漏洞程序就可以完成任意的操作。同時,它不利用完整的庫函數,因此也不依賴于函數調用時通過堆棧傳遞參數。

一般我們通過 immunitydbg 配合 mona 的腳本插件提取 rop 的指令序列構造 rop chain。

Rop chain 展示:

IE漏洞攻防編年簡史

圖 1.2.7

Rop 的出現一度使得在 XP 時代的攻擊者占據上風。由于 dll 加載地址的固定。針對不同的 IE 版本然后提取 rop chain 的工作雖然讓人感覺無趣但是達成的攻擊效果的確不錯。但是作為防御一方的微軟的腳步并沒有停止。Vista 系統的臃腫繁雜為人所詬病并且市場份額也并不高。但是從 Vista 系統引入的由 Win7 沿襲的 ASLR 機制卻結結實實的又一次提高了攻擊的門檻。

在 Rop 攻擊中,攻擊者可以事先預知特定的函數如 system 或者 VirtualProtect 的入口地址。這是因為在 XP 以及 2000 的操作系統上面,由于 kernel32.dll 這些動態鏈接庫加載地址是固定的,所以導致相關的函數入口地址也是固定的即攻擊者可以事先確定這些函數的入口地址。

當然 Rop 這一技術有一個弊端就是針對不同的操作系統要編寫提取不同的 rop chain。這使得兼容性并不是很好。

ASLR 全稱 Address space layout randomization,是系統級別的特性,率先在 Vista 操作系統中得到支持。它的原理就是在當一個應用程序或動態鏈接庫 ,如 kernel32.dll,被加載時,如果其選擇了被 ASLR 保護 ,那么系統就會將其加載的基址隨機設定 。這樣 ,攻擊者就無法事先預知動態庫,如 kernel32.dll 的基址,也就無法事先確定特定函數,如 VirtualProtect 的入口地址了。

如果感興趣,可以自己寫一段簡單的C代碼打印出 VC 運行庫的加載地址。會發現每次重啟之后 win7 下面 VC 運行庫加載地址是變化的,但是 XP 系統 VC 的運行庫加載地址就是固定的。    

Heap Spray

ASLR 在新系統上面的應用又使得相當長的一段時間在緩沖區溢出利用時代攻擊方陷入了弱勢。但是攻擊者發現之前很早就被提出的(2001 年左右)heap spray 正好可以解決這個問題。基本在 2005 年之后 IE 漏洞的利用很多都用到了 Heap Spray 的技術。

在緩沖區溢出的時候,我們能夠劫持覆蓋一個地址,從而使得程序崩潰,但是只使得程序崩潰這樣是沒有價值的接下來如何將程序的執行流程交接到 shellcode 的手中,這就變成了一個問題。如果覆蓋到一個固定的地址比 0x0C0C0C0C,0x0A0A0A0A,0x0D0D0D0D 而恰好從這個地址開始布滿了我們的 shellcode。這樣觸發漏洞的時候就轉入了我們的 shellcode 進行了惡意代碼的執行。

實際應用當中 shellcode 前面都是要加上一些 slidecode 的(滑板指令)。為什么要加入滑板指令而不是全用 shellcode 去填充呢。因為如果要想 shellcode 執行成功,必須要準確命中 shellcode 的第一條指令,如果整個進程空間都是 shellcode,反而精確命中 shellcode 的概率大大降低了,因為必須要命中第一條指令,加上 slidecode 之后,現在只要命中 slidecode 就可以保證 shellcode 執行成功了,一般 shellcode 的指令的總長度在 50-100 個字節左右,而 slidecode 的長度則大約是 100 萬字節(按每塊分配 1M 計算),那么現在命中的概率就接近 99.99% 了。因為現在命中的是 slidecode,那么執行 slidecode 的結果也不能影響和干擾 shellcode。但是如果單純使用0×90(NOP)指令進行填充,因為現在使用較多的攻擊場景是覆蓋虛函數指針(這是一個多級指針),這種情況下如果你使用0×90 來做 slidecode,而用 0x0C0C0C0C 去覆蓋虛函數指針,那么現在的虛表(假虛表)里面全是0×90909090,程序跑到0×90909090(內核空間)去執行,直接就 crash 了。根據這個流程,你可以看到,我們的 slidecode 也選取 0x0C0C0C0C 就可以了。

IE漏洞攻防編年簡史

(圖 1.2.8)

大概大量分配內存之后分別覆蓋到的地址是這樣的:

  0x0A0A0A0A(160M),
  0x0C0C0C0C(192M),
  0x0D0D0D0D(208M)

網馬里面進行堆噴時,申請的內存大小一般都是 200M 的原因,主要是為了保證能覆蓋到 0x0C0C0C0C 地址。(圖 1.2.9)

IE漏洞攻防編年簡史

2. 1 UAF 時代

由于緩沖區類漏洞由于發掘起來相對簡單,在攻防對抗的時間長河中這類漏洞資源很快耗盡。08 年之后釋放重利用這樣漏洞利用方式變成了 IE 漏洞的主流。逐漸在這幾年達到了高峰。對象畸形操作類的漏洞一般來說觸發漏洞需要一系列的操作。單個的操作,比方說對象的創建使用刪除都是正常的。導致問題的是對于對象操作的畸形的組合。由于沒有標準的章法可供參考,基于傳統的溢出類漏洞的發掘手段已經不甚適用。

2. 2 對象操作類漏洞原理

跟面向過程的編程語言不同,c++支持多態和繼承。支持這些機制的核心就是虛表。C++的(虛)函數指針位于一個全局數組中,形成虛表。而指向這個虛表的指針(VSTR)一般位于對象實例在內存中開始的 4 個字節(32 位系統).

之后才是類中聲明的數據成員,一般按照聲明的先后順序排列。對于存在多態行為的類,子類的所有實例共享相同的虛表,但區別于父類的虛表。對于某個對象,其調用存在多態行為的某個函數時,會先通過虛表指針得到虛表.再根據函數在虛表中的偏移來得到相應的函數指針,最后才會調用函數。

另外,對象所在的地址一般通過 ecx 等寄存器傳遞。因此.C++中調用存在多態行為的函數的反匯編代碼類似于如下序列:

IE漏洞攻防編年簡史

(圖 2.2.1)

我們以 stackexchange 上面 Polynomial 給出的示范代碼對 UAF 做一下簡介。

如下例的這樣的一段 C++ 代碼:

IE漏洞攻防編年簡史

圖 2.2.2

可以衍生為:

IE漏洞攻防編年簡史

注意,當執行到 Account_GetBalance 的時候,由于 Account_Destroy 函數的執行 myAccount 指針指向的內存已經是一個不確定的狀態。如果此時能夠可靠的觸發 Account_Destroy 函數。并且填充一塊精心構造的內容到 myAccount 指針指向的內存,時機在 Account_Destroy 執行后 Account_GetBalance 執行之前。很多情況下這是可能實現的。   

Account_Create 函數執行之后分配了 8 個字節的內存。Balance 和 transactionCount 分別占據 4 個字節,并且返回一個指向他們的指針。這個指針儲存在 myAccount 變量當中。Account_Destroy 釋放了這塊內存,但是 myAccount 變量依然指向那個 8 字節的內存。我們將 39 05 00 00 01 00 00 00 這 8 字節內容可靠的進行內存分配。由于舊的 8 字節內存塊已經被標記釋放,所以內存管理器有很大可能會用新分配的內存去覆蓋掉舊的內存塊到那 8 個字節已經被釋放的內存。這個時候 Account_GetBalance 函數被調用了,他會去讀取那 8 個字節的內存塊,但是實際上那 8 字節的內存塊已經被我們覆蓋成了

Balance    39 05 00 00   (1337)   
transactionCount    01 00 00 001

所以我們已經越權執行到了下一個函數。

當然具體到 IE 當中,由于對象繁雜,UAF 就更為錯綜復雜。

瀏覽器中跟對象操作類漏洞相關的對象有 DOM ,BOM ,JavaScript 對象。我們以 DOM 對象的分配過程為例。

DOM (文檔對象模型)提供了操作 HTML/XML 文檔的接口。IE 瀏覽器中跟 DOM 實現相關的代碼主要在 mshtml dll 中。mshtml 中的 CMarkup 類負責構造整個 htmI 樹結構,其成員函數 CreateElement 會調用全局的 CreateElement 函數束構造不同標簽對應的元素。比如<object>標簽.會構造對應的 CObjectElement 元素:<area>標簽.會構造對應的 CAreaElement 元素。這些 Element 類都是 CElement 類的子類。接下來的逆向工作主要基于 IE8  8.00.7601.17537 版本的 mshtml dll。

對于每個不同的標簽,IE 測覽器內部有不同的 CTagDesc 結構。這些 CTagDesc 結構中的其中一項就是對應元素的 CreateElement 函數指針。因此,全局的 CreateElement 函數,會根據不同的標簽柬獲得對應的 CTagDesc 結構,然后再從里面取得對應該標簽的 CreateElement 函數指針然后 call 過去進行調用。具體可參看全局 CreateElement 函數的反匯編代碼,如圖 2.2.6 所示。

IE漏洞攻防編年簡史

IE漏洞攻防編年簡史

這里有一些小細節,有的時候直接用 IDA 反匯編如 mshtml dll 這樣的 dll 文件的時候沒有找到對應的符號表,可以先使用 Symbol Type Viewer 這樣的小工具將符號表下載下來放到跟 dll 同目錄然后再使用 IDA 對相關的 dll 文件進行反匯編。

IE漏洞攻防編年簡史

接下來,以 CObjectElement 為例,介紹其創建過程,其他 Elenlent 的創建過程類似。CObjectElement 的初始化是在成員函數 CrcateElement 函數中完成的。創建過程如下:先分配內存,然后調用構造函數,最后將返回的對象指針保存在傳入的 CElemen**參數中。反匯編代碼如圖。

IE漏洞攻防編年簡史

圖 2.2.9

HeapAlloc 進行堆內存分配,高版本的一些 mshtml dll 中可能是由 ProcessHeapAllocClear 這個函數進行內存的分配。傳給 HeapAlloc 的字節數是 0E0h 可知,當前 IE 瀏覽器版本中的 CObjectElement 大小為 E0h。

接下來調用 CObjectEtemem 的構造函數完成 CObjectElement 對象的初始化,構造函數會自動調用父類的構造函數。調用完構造函數后.會將新建的 CObjcctElemenl 對象指針保存在傳入的參數 CElemen**中。這是通過代碼完成的。

mov ecx,[ebp+arg_8]
mov[ecx],eax

IE 瀏覽器采用引用計數束跟蹤 DOM 對象的生命周期。引用計數(Reference Counting)算法對每個對象計算指向它的指針的數量。當有一個指針指向該對象時計數值加 1 ,當刪除一個指向酸對象的指針時,計數值減l。如果計數值減為0,說明不存在指向該對象的指針.此時就可以安全的銷毀潑對象。垃圾回收過程就是回收引用計數為 0 的對象。引用計數算法的優點是算法實現簡單,并且進行垃圾回收時無需掛起應用程序,回收速度快。

缺點是出于每一次對對象的指針操作都要對對象的引用計數進行更新,因此會減緩系統的整體運行速度。另外,使用引用計數算法的每個對象都需要額外的空問存儲計數值。除此之外,引用計數算法的最大缺點是無法處理循環引用。循環引用指的是兩個對象互相指向對方。此時兩個對象的引用計數都依賴于對方.因此始終無法減至0。

IE 瀏覽器實現引用計數的核心就是 IUnknown 接口。該接口提供了兩個非常重要的特性:生存期控制與接口查詢。對象內部通過引用計數來實現對象的生存期控制。調用程序不甩在意對象的內部實現細節.通過接口查詢即可獲得指向對象的指針。IE 瀏覽器中的很多類都繼承于 IUnknown。IUnknown 有三個方法。

IE漏洞攻防編年簡史

圖 2.2.10

以上節介紹的<obiect>標簽的內部實現 CObjectElement 類為例.該類最終繼承于 CElement。而 CElement 繼承于 CBase,CBase 則實現了 IUnknown 接口。用戶要查詢<object>標簽對應的 CObjectElement 對象,需要調用 CObjectElement::QueryInterface 函數。而 CObjectElement 的 QueryIntefface 函數最終會調用到 CElement 的 QueryInterface 接口.CElement 的 QueryInterface 接口最終會調用 PrivateQueryInterface 來獲得對象指針。

PrivateQueryInterface 會先調用 CElement::CreateTearOffThunk 函數退回對象包裝后的指針.然后在接下來調用 CCaret::AddRef 函數(call eCX)增加引用計數。

而 CElement::CreateTearOffThunk 函數僅僅是簡單的調用全局的 CreateTearOflThunk 函數。全局的 CreateTearOflThunk 函數反匯編部分代碼如圖

IE漏洞攻防編年簡史

圖 2.2.11

再來看看釋放引用時所做的工作。對于 CElement,用戶不再需要其引用時,調用 CElement::Release 即可。CElement::Release 是對 CElement::PrivateRelease 的封裝,而 CElemem::PrivateRelease 主要的工作是調用父類 CBase 的 PrivateRelease 函數。CBase::PrivateRelease 負責減少引用計數。

實際上 IE 當中這種對對象的創建和銷毀的場景比比皆是,這也是在緩沖區漏洞在 IE 上面幾近絕跡后 UAF 中興的基礎。     

2. 3 時代關鍵字

Deferred/Delayed Free Control Flow Guard Isolated Heap

上文已經簡單的給出一個例子幫助理解 UAF 的成因和觸發了。但是由于 IE 中對象眾多調用關系復雜,微軟作為防守的一方并不能像挖掘緩沖區溢出漏洞一樣容易的窮舉并修復所有潛在的漏洞。但是微軟分別以發布補丁的方式在 14 年的 6 月和 7 月分別引入了隔離堆和延遲釋放的漏洞利用緩解措施。并且在 Win8.1Update3 和 Win10 中引入了新的機制 Control Flow Guard。我們簡單記錄說明一下這些機制。

UAF 的觸發和利用依賴于被釋放的對象的重用。利用的過程必須依賴非法 IE 對象被確定的分配和釋放。而隔離堆和延遲釋放分別在對象的分配和釋放的時候加入了保護。

在 IE 中 CVE-2014-0282 修補前 CTextArea::CreateElement 分配內存的時候有這樣的代碼

IE漏洞攻防編年簡史

圖 2.3.1

漏洞修補之后代碼是這樣的。

IE漏洞攻防編年簡史

圖 2.3.2

可以比較明顯的看到存在 UAF 隱患的對象的內存分配已經單獨使用了隔離堆進行內存分配。

而延遲釋放是這樣的。正常的對象釋放使用 HeapFree 就立即釋放了,而加入延遲釋放之后需要被釋放的對象會被統一記錄然后根據規則再進行延遲釋放。

再說一下 CFG (Control Flow Guard)這個機制。CFG 的機制是基于控制流完整性 Control-Flow Integrity 的設想。這里通過對二進制可執行文件的改寫,對 jmp 的目的地址前插入一個在改寫時約定好的校驗 ID,在 jmp 的時候看目的地址前的數據是不是我們約定好的校驗 ID,如果不是則進入錯誤處理流程。

IE漏洞攻防編年簡史

圖 2.3.3

在 Call 的過程中會引入一個 CFG 的校驗函數。CFG 需要編譯器和操作系統的雙重配合。當這個校驗函數在不支持的操作系統上運行的時候直接就 return 了。當在被支持的操作系統(win10 和 win8.1 update3) 的時候就會跳轉到一個 ntdll 里面的一個檢測函數。檢測的機制我們不在詳細展開。

由于在溢出漏洞和 UAF 的大部分利用當中都依賴于覆蓋某個地址然后劫持程序的 EIP 跳轉到我們的惡意代碼的地址進行執行。CFG 在控制非法地址跳轉方面直接斬斷了大部分漏洞利用的可能。

3. 1 后 UAF 時代

就目前來看,14 年之后由于新的緩解措施的加入使得攻防雙方的優勢幾乎一邊的倒向了微軟為首的防守者的陣營。

瀏覽器的漏洞利用已經沒有固定的套路。如瀏覽器內部的腳本引擎的設計錯誤導致從腳本層面突破 IE 而進行漏洞的相關利用(CVE-2014-6332),對瀏覽器中 flash 插件的漏洞發掘利用得到 ring3 權限,然后配合對較老字體解析引擎代碼發掘出來的提權漏洞再進行提權拿到系統權限(Hacking Team 相關利用)。漏洞利用方式不一而足,有機會在修訂簡史的時候一并補充。                 

0×03 IE 漏洞防護措施關鍵時點

2015 年 7 月 CFG 編譯器支持 VS2015 RTM 版本引入/guard 開關對 Control Flow Guard 特性提供編譯器支持。

2014 年 11 月 CFG 系統級別支持 Windows 8.1 update3 對 Control Flow Guard 提供系統層面的支持,之后的 windows 系統均在操作系統層面支持該特性。

2014 年 7 月 MS14-037 補丁發布引入 Delayed  Free 特性。

2014 年 6 月 MS14-035 補丁發布引入 Isolated  Heap 特性。

2008 年 1 月 SEHOP 系統級別支持發布 vista Service Pack 1 補丁包,引入對 SEHOP 特性的操作系統支持。自 vista sp1 后的 windows 系統均在操作系統層面支持該特性。

2007 年 1 月 ASLR 系統級別支持 windows vista 系統引入對 ASLR 特性操作系統級別的支持。自 vista 后的 windows 系統均在操作系統層面支持該特性。

2006 年年初 safeseh/stack cookie/aslr/dep 編譯器支持 VS2005 引入/safeseh 編譯開關緩和溢出漏洞對 seh 的攻擊,引入/GS 編譯開關插入 Stack Cookie 緩和對返回地址的攻擊,加入/dynmicbase 編譯開關引入對 ASLR 特性的編譯器支持,加入/NXCOMPAT 編譯開關引入對 DE 特性的編譯器支持。自 VS2005 之后的編譯器均支持上述編譯開關。

2004 年 8 月 DEP 系統級別支持。微軟推出 XP Service Pack 2 補丁包引入對 DEP 特性的操作系統支持,自 XP SP2 后的 windows 系統均在操作系統層面支持該特性。

作者:阿爾法實驗室,轉載請注明來自 FreeBuf 黑客與極客

來自: www.freebuf.com

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!