在過去的二十幾年,Windows做爲網絡安全的主戰場之一,攻於防的較量從未停息過。內存破壞漏洞做爲研究的重點之一,經歷了不少的發展也沉澱了前輩們許多經驗和智慧。javascript
本人根據大牛們的各類報告總結了目前Windows平臺上內存破壞漏洞利用與防禦的發展史,接下來會從應用層和內核層兩個方面逐一介紹。php
先來看一下總的架構圖:
html
應用層漏洞的目的都是爲了執行任意代碼,因此分爲得到執行流+執行shellcode兩部分介紹:java
1.1 總覽web
發展歷史算法
下圖是微軟在Black Hat 2012的演講ppt中的一頁shell
目前情況windows
a. 很是難以利用:在GS+SEHOP+SEH共同防禦下。數組
b. 在編譯器的幫助下,漏洞自己的數量也在減小。下圖是Windows 2000到Windows 7,各類類型漏洞數量的比例,但是看出,棧溢出漏洞已經大幅減小:
瀏覽器
1.2 最原始的利用
向局部變量填充大量的數據,直至覆蓋返回地址,等到函數返回的時候,達到劫持EIP獲取執行流目的。
1.3 GS
1.3.1. 概念
由Crispin Cowan提出,在編譯器(從VS7.0開始)的幫助下,在發生函數調用的時候會向棧中壓入一個隨機數,函數返回的時候會和在.idata中的值作對比。
1.3.2. GS v1.0
a. 概念
VS 2002 加入
Epilogue checks cookie & terminates on mismatch
b.繞過方法
覆蓋SEH,在函數返回以前,製造一個異常
Bypass by replacing cookie on stack and in .data section
若是有能力肯定cookie存儲的位置的話
Bypass because not all buffers are protected(arg_0 for example)
Bypass by overwriting stack data in functions up the stack
好比某個對象或者結構的指針做爲當前函數的參數,那麼這個值是在當前函數的棧中的,也就是臨時變量,這樣能夠經過直接改寫來劫持EIP。
好比覆蓋對象的virtuali function call table
Bypass because the cookie is static.(haha)
1.3.3. GS v1.1
a. 概念
1.3.4. GS v2.0
a. 概念
VS2005加入
strict GS pragma
b.繞過方法
1.3.5. GS v3.0
a. 概念
Remove unnecessary checks
參考 http://blogs.technet.com/b/srd/archive/2009/03/20/enhanced-gs-in-visual-studio-2010.aspx
1.4 SafeSEH
a. 概念
VS2003加入
編譯選項/safeSEH,編譯器在編譯的時候會創建一個全部已知異常處理函數地址鏈表,當異常發生的時候會檢查這個鏈表,若是是非法地址,則會當即結束進程。
也稱爲軟件DEP
b.繞過方法
Try not to use SEH based exploit
開啓了SEH可是未開啓GS的進程。(haha)
Point corrupted handler to somewhere other than an image or the stack
由於這種地址不受safeSEH的影響,因此只要在其中找到一條跳轉指令就能夠了
利用虛函數繞過
1.5 SEHOP
a. 概念
b. 繞過方法
僞造SEH鏈表
因爲ASRL,stack的地址獲取是個問題,信息泄露?
2.1 總覽
a.發展歷史
2.2 最原始的利用
a. 利用堆的鏈表管理特色,操做這個鏈表的時候就能夠構造一個write4
b.Write What?
2.3 安全機制
2.3.1 Win XP & Windows Sever 2003
a.Safe Unlinking
概念
鏈表項在卸載時候會檢查鏈表的完整性
b.Heap entry header cookie
概念
一個8位的校驗隨機數,heap free 的時候進行驗證
c.Pointer encoding
概念
Protect UEF,VEH,and others via EncodeSystemPointer
繞過方法
參考
David Litchfield. Windows Heap Overflows. Black Hat USA. 2004
Alexander Anisimov. Defeating Microsoft Windows XP SP2 Heap protection. 2004
2.3.2 Windows Vista~Windows 7
a.Removal of commonly targeted data structures
such as lookaside lists and array lists
lookaside replaced by the Low Fragmentation Heap (LFH)
b.Heap entry metadata randomization
c.hardening heap cookies
extend checking heap metadata scope,verified in more places,not only when the entry is freed.
d.Function Pointer encoding
Function pointers (e.g. CommitRoutine) in heap data structures are encoded with a random value
e.Termination on heap corruption
檢測到異常的時候,直接終止程序
f.Algorithm variation
改進算法,更難預測堆的狀態
g.RtlDeleteCriticalSection technique mitigated by RtlSafeRemoveEntryList
h.FreeList[0] technique mitigated by RtlpFastRemoveFreeBlock
繞過方法
參考:
Modern Heap Exploitation using the Low Fragmentation Heap. Chris Valasek.2011
Attacking the Vista Heap. Ben Hawkes. Nov,2008
Ghost in the Windows7 Allocator.StevenSeeley,2012
2.3.3 Windows 8
a.guard pages
b.allocation order randomization
c.LFH design changes & integrity checks
這裏針對的是IE瀏覽器。
3.1 概念
a.利用可控的假對象替代真對象(內存佔位),劫持程序流程
b.attack class object instead of heap metadata/mechanism
3.2 防禦
a. 延遲釋放
要釋放的內存不會當即釋放,而是先併入到一個待釋放鏈表中,大小達到100000的時候纔會釋放掉。
b. 隔離堆
大多數的DOM對象和相關的類都分配到一個單獨的堆中,和一般用來佔位的對象好比mshtml string、javascript string等分隔開來,防止佔位。
c.Virtual Table Guard
相似cookies,在調用虛函數以前會check一下。
d.Sealed optimization
經過編譯器,從源頭減小虛函數的間接調用。
繞過方法
2.1 概念
2.1.1. 軟件DEP
2.1.2. 硬件DEP
須要CPU的支持,一般意義上的DEP,經過修改相關頁面的PTE,加入特殊的標識位來達到目的
a. Windows Xp SP2加入
b. 原理圖
c. 工做狀態
Optin
默認僅爲windows系統組件和服務提供,從Vista 開始具備/NXcompat編譯選項的程序也會歸入到這個範圍內。
通常用於用戶版的操做系統。
Optout
默認爲排除列表之外的全部程序和服務啓動DEP。
通常用於服務器操做系統。
AlwaysOn
不存在排除列表這種東西,全部的進程和服務都在內
只有64位的系統,不能夠被關閉
AlwaysOff
對全部進程都禁用
不可以動態的被開啓
其中前面兩種狀況都是能夠動態的關閉的。
d. 繞過方法
ROP:經過在模塊中尋找指令,組成代碼段調用函數關閉DEP。
VirtualProtect
改變目標內存地址屬性爲可執行
Disable DEP for the process(NtSetInformationProcess)
設置進程結構KPROCESS中相關標誌位
VirtualAllocEx
分配一塊可執行(RWX)的內存
3.1 概念
3.1.1. Windows Vista 引入
3.1.2.
目前全部的漏洞利用都有一個共同的特徵:須要肯定一個固定地址。好比JMP ESP等跳板和ROP所使用指令的地址。因此微軟加入了地址隨機化來防止得到穩定的地址。
3.1.3.
映像隨機化
當PE文件映射到內存的時候,系統會對其映射的虛擬地址作隨機化處理。
每次系統重啓後,地址不一樣。
能夠在註冊表中設置
堆棧隨機化
程序隨機化的堆棧基地址。
每次程序重啓時都不一樣。
3.2 繞過方法
3.2.1. 攻擊未啓動ASLR的模塊
3.2.2. Address space spraying(heap/JIT)
http://www.semantiscope.com/research/BHDC2010/BHDC-2010-Paper.pdf
3.2.3. 預測內存
3.2.4. 信息泄露
參考:
3.3 Windows 8
防禦機制
Force ASLR
進程能夠強制non-ASLR images 隨機化
Bottom-up & top-down randomization
更難預測內存狀態。
隨機化的程度提升
去掉了一些能夠泄露內存的路徑
4.1 概念
4.1.1
從Win8.1 Update3加入,Win10中正式啓用。
4.1.2
代碼表示
before
after
4.1.3
圖解
4.2 繞過方法
綠盟的研究員張雲海在BlackHat的議題,思路就是「Overwrite Guard CF Check Function Pointer」,因爲該地址只讀屬性,找到了一個magic object,可以改寫該地址屬性。
參考
mj0011,Windows 10 Control Flow Guard Internals
到此,應用層的漏洞利於與防禦介紹完了,下面是內核層的。
總的來講,內核層和應用層有着諸多類似的地方,可是也有着本身的特色,好比空指針解引用漏洞,SMEP防禦機制等。
有趣的是,一些相同原理的防禦機制,滯後於對應的應用層好比:Safe Unlink在win7纔開始加入到內核防禦中,應用層的Safe unlink防禦早在WinXP就加入了。
下面按照和應用層相同的思路介紹,分爲劫持執行流和執行shellcode兩部分。可是要注意的是:
可能不須要執行shellcode,直接提權成功,好比CVE-2014-4113在win8 x64上的利用和CVE-2015-1701的利用
1.1 最原始利用
大量數據直至覆蓋返回地址-->改寫EIP,得到執行流
1.2 stack cookies
1.2.1 概念
1.2.2 繞過方法
注意try catch不能捕獲全部的頁異常處理,在內核中引用一塊無效地址會致使BSOD,因此這裏有一個技巧:
memcpy的時候就觸發異常,不要等到函數返回的時候,或者strcat這種操做的時候
參考:
A Guide to Kernel Exploitation Attacking the Core
Win8 x64以前:成功率大於46%。
J00ru:Windows Kernel-mode GS Cookies subverted
Win8 x64以後:很是困難。
參考:
mj0011,Using a Patched Vulnerability to Bypass Windows 8 x64 Driver Signature Enforcement
2.1 最原始利用
相似用戶層堆,利用堆鏈表管理的特色,構造Write 4。
2.2 Write what
HalDispatchTable+4(經常使用)
修改其爲shellcode的地址,而後在用戶層調用 NtQueryIntervalProfile(2,X)觸發shellcode執行。
Token+ PrivilegesOffset.Enabled
修改SeDebug權限,以後能夠注入代碼到系統進程中,完成提權
Moritz Jodeit,Exploiting CVE-2014-4113 on Windows 8.1
KiDebugRoutine?
2.3 Win7 以前
2.3.1 安全機制
彷佛沒有。。。
2.3.2 繞過方法
主要發生在ListEntry中,在下面幾種堆管理的狀況下,又可能將溢出變成Write4:
Unlink in merge with next
Unlink in merge with previous pool chunk
Unlink in allocation from ListHeads[n] free list
參考:
2.4 Win7
2.4.1 安全機制
Safe Unlink
相似應用層的Safe Unlink,圖示:
2.4.2 繞過方法
參考:
Tarjei Mandt BH DC 2011
2.5 Win8
2.5.1 安全機制
都是針對win7上的利用作得改進。
2.5.2 繞過方法
DKOHM / Object Type Confusion(重要)
參考:
Tarjei Mandt BH US 2012
Zhenhua 'Eric' Liu NoSuchCon 2013
Nikita Tarakanov--Exploiting Hardcore Pool Corruptions in Microsoft Windows Kernel NoSuchCon 2013
Nikita Tarakanov--DATA-ONLY PWNING MICROSOFT WINDOWS KERNEL: EXPLOITATION OF KERNEL POOL OVERFLOWS ON MICROSOFT WINDOWS 8.1 ZeroNights 2014
2.6 總結
愈來愈多的pool integrity checks,針對pool metadata/mechanisms的攻擊愈來愈困難,DKOHM是一個趨勢。
3.1 空指針解引用
3.1.1 利用
這算是內核中比較特殊而且數量較大的一類漏洞了,雖然應用層也有空指針解引用漏洞,可是幾乎都不能利用。而在Win8以前倒是內核漏洞中很流行。
好比CVE-2014-411三、CVE-2015-0003等都是這種漏洞,形式相似:
call [eax+8] // eax=0
具體能夠參考這兩個漏洞的利用代碼,都是公開的。
3.1.2 防禦
win8 開始禁止非管理員權限的零頁分配
3.2 UAF
3.2.1利用
和應用層相似,可是也有本身特殊的地方,好比神奇的WorkerFactoy 對象。
參考:0x710DDDD,CVE-2014-1767_Afd.sys_double-free_漏洞分析與利用
3.2.2防禦
Reference count hardening
3.3 競爭條件
這類漏洞一直沒能找到相關的PoC,因此並不瞭解,能夠參考:
http://j00ru.vexillium.org/?p=1695
大多數的漏洞都須要這一步,也有像CVE-2014-4113在win8上面的exp,利用了漏洞自己的特色,再也不須要」shellcode「了。
1.1 概念
SMEP:處理器cr4寄存器和PTE結合,阻止ring0去執行ring3代碼(Prevents supervisor from executing code in user pages)
SMAP:Supervisor Mode Access Prevention,ring0的代碼不能夠read/write應用層的內存。
1.2 繞過方法
思路相似於繞過DEP。
ROP
ExAllocatePoolWithTag (NonPagedExec) + memcpy+jmp
clear SMEP flag in cr4
參考:
http://blogs.360.cn/blog/hacking-team-part5-atmfd-0day-2/
Win8以前
經過肯定的對象地址,寫入一些代碼
可是win8 加入了 non-paged pool NX
mj0011,Reversing Windows8: Interesting Features of Kernel Security
2.1 概念
non-executable non-paged pool
參考
https://msdn.microsoft.com/en-us/library/windows/hardware/hh920391(v=vs.85).aspx
3.1 概念
微軟在Win8.1以前,對這方面都是很重視,第一次是在Server2008 RTM引入的。
4 bits of entropy for drivers,5 bits for NTOS/HAL
3.2 防禦
3.2.1 Win7
Drivers: 6 bits on x86, 8 bits on x64
3.2.2 Win8
Biasing of kernel segment base
NTOS/HAL receive 22 bits(64-bit) and 12 bits(32-bit)
Various boot regions also randomized(P0 idle stack)
限制對敏感函數的調用
若是進程運行在低完整性級別如下(保護模式或加強保護模式),那麼SystemModuleInformation等相關得到內核模塊基址的方法都會被阻止,這樣,即便攻擊者在保護模式或加強保護模式下觸發了內核漏洞,因爲沒法得到內核基址,也很難進行進一步利用。
參考:
http://blogs.360.cn/blog/fixed_three_0days_in_may/
圖解:
by:會飛的貓
轉載請註明:http://www.cnblogs.com/flycat-2016