在过去的二十几年,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