各种保护机制绕过手法

                             各种保护机制绕过手法

一.绕过GS编译选项

●原理:通过VC++编译器在函数前后添加额外的处理代码,前部分用于由伪随机数生成的cookie并放入.data节段,当本地变量初始化,就会向栈中插入cookie,它位于局部变量和返回地址之间

 

●绕过方法:

1.猜测/计算cookie

  Reducing the Effective Entropy of GS Cookies:http://www.uninformed.org/?v=7&a=2&t=html

  至从覆盖SEH的方法出现后,这种方法目前已基本不用了,它没有后面的方法来得简便

 

2.覆盖SEH

  由于当security_check_cookie()函数检测到cookie被更改后,会检查是否安装了安全处理例程,也就是SEH节点中保存的指针,如果没有,那么由系统的异常处理器接管,因此我们可以通过(pop pop ret)覆盖SEH来达到溢出的目的。但对于受SafeSEH保护的模块,就可能会导致exploit失效,关于它的绕过在后续部分再述

辅助工具:OD插件safeSEH、pattern_create、pattern_offset、msfpescan、memdump

 

3.覆盖虚表指针

堆栈布局:[局部变量][cookie][入栈寄存器][返回地址][参数][虚表指针]

当把虚表指针覆盖后,由于要执行虚函数得通过虚表指针来搜索,即可借此劫持eip

 

4.利用未被保护的内存突破

 

5.替换.data中的Cookie突破GS

 

二.SafeSEH

●原理:

为了防止SEH节点被攻击者恶意利用,微软在.net编译器中加入/sdeseh编译选项引入SafeSEH技术。编译器在编译时将PE文件所有合法的异常处理例程的地址解析出来制成一张表,放在PE文件的数据块(LQAJ)一C0N—FIG)中,并使用shareuser内存中的一个随机数加密,用于匹配检查。

如果该PE文件不支持safesEH,则表的地址为0。当PE文件被系统加载后,表中的内容被加密保存到ntdl1.dll模块的某个数据区。在PE文件行期间,如果发生异常需要调用异常处理例程,系统会逐个检查该例程在表中是否有记录:如果没有则说明该例程非法,进而不执行该异常例程

 

●绕过方法:

1.利用没有启动SafeSEH保护的模块(比如漏洞软件本身自带的dll文件,可以借助OD插件SafeSEH来查看进程中各模块是否开启SafeSEH保护)

2.攻击没有开启GS的函数

3.覆盖虚表指针

4.利用堆绕过

5.利用某些ActiveX控件绕过

三.DEP绕过(数据执行保护)

●绕过方式:

1.某些程序没有启动DEP保护

2.Ret2Libc(最后可以执行ZwSetInfomationProcess,VirtualProtect,VitualAlloc)(ROP)

3.某些可以执行的内存(比如,Java Applet中动态申请中动态申请的内存空间具有可执行属性)

4.利用某些.Net控件和Java控件来绕过

5.利用TEB突破DEP(局限于XP SP2以下的版本)

6.利用WPN与ROP技术

ROP(Return Oriented Programming):连续调用程序代码本身的内存地址,以逐步地创建一连串欲执行的指令序列.WPM(Write Process Memory):利用微软在kernel32.dll中定义的函数比如:WriteProcess Memory函数可将数据写入到指定进程的内存中。但整个内存区域必须是可访问的,否则将操作失败

7.利用SEH绕过DEP

启用DEP后,就不能使用pop pop ret地址了,而应采用pop reg/pop reg/pop esp/ret 指令的地址,指令 pop esp 可以改变堆栈指针,ret将执行流转移到nseh 中的地址上(用关闭NX 例程的地址覆盖nseh,用指向pop/pop /pop esp/ret 指令的指针覆盖异常处理器)

 

四.ASLR绕过(地址随机化)

●绕过方式:

1.基地址泄露漏洞,某个dll模块的某个内存地址的泄露,进而可以泄露该DLL的基地址,进而可以得到任意DLL的基地址

 

2.某些没有开启地址随机化的模块

   当浏览器加载一个带try location.href = ‘ms-help://’ 语句的页面时,HXDS.DLL就会被加载,而该DLL并没有开启地址随机化

利用该方法的CVE-2013-3893, CVE2013-1347, CVE-2012-4969, CVE-2012-4792

 

3.堆喷射需要配合没有开启地址随机化的模块

 

4.覆盖部分返回地址

    虽然模块加载基地址发生变化,但是各模块的入口点地址的低字节不变,只有高位变化

对于地址0×12345678,其中5678部分是固定的,如果存在缓冲区溢出,可以通过memcpy对后两个字节进行覆盖,可以将其设置为0×12340000 ~ 0x1234FFFF中的任意一个值。

   如果通过strcpy进行覆盖,因为strcpy会复制末尾的结束符0×00,那么可以将0×12345678覆盖为0×12345600,或者0×12340001 ~ 0x123400FF。

   部分返回地址覆盖,可以使得覆盖后的地址相对于基地址的距离是固定的,可以从基地址附近找可以利用的跳转指令。

这种方法的通用性不是很强,因为覆盖返回地址时栈上的Cookie会被破坏。不过具体问题具体分析,为了绕过操作系统的安全保护机制需要考虑各种各样的情况。

 

5.java Applet Spray:Java Applet中动态申请中动态申请的内存空间具有可执行属性,可在固定地址上分配滑板指令(如Nop和ShellCode),然后挑转到上面地址执行。和常规的HeapSpray不同,Applet申请空间的上限为100MB,而常规的HeapSpray可以达到1GB

 

6.just in Time Compliation(JIT)即时编译,也就是解释器(如python解释器),主要思想是将ActionScript代码进行大量xor操作,然后编译成字节码,并且多次更新到Flash VM,这样它会建立很多带有恶意xor操作的内存块vary=(0×11223344^0×44332211^0×4433221);

正常情况下被解释器解释为:

如果非常规的跳转到中间某一个字节开始执行代码,结果就是另一番景象了:

   关于JIT的详细介绍,可以参考

Pointer Inference and JIT Spraying以及

Writing JIT-Spray shellcodefor fun and profit 

Pointer Inference and JIT Spraying

Writing JIT-Spray shellcode for fun and profit

 

7.某些固定的基地址

★从Windows NT 4到Windows 8,

   (1)SharedUserData的位置一直固定在地址0x7ffe0000

   (2)0x7ffe0300总是指向KiFastSystemCall

   (3)反汇编NtUserLockWorkStation函数,发现其就是通过7ffe0300进入内核的

利用方法:

这样,在触发漏洞前合理布局寄存器内容,用函数在系统服务(SSDT / Shadow SSDT)中服务号填充EAX寄存器,然后让EIP跳转到对应的地方去执行,就可以调用指定的函数了。但是也存在很大的局限性:仅仅工作于x86 Windows上;几乎无法调用有参数的函数

 

★64位Windows系统上0x7ffe0350总是指向函数ntdll!LdrHotPatchRoutine

  (经过验证可能不是这个地址,但是这个地址在开启了ASLR后是固定的)

利用方法:

在触发漏洞前合理布局寄存器内容,合理填充HotPatchBuffer 结构体的内容,然后调用LdrHotPatchRoutine

   (1)如果是网页挂马,可以指定从远程地址加载一个DLL文件;

   (2)如果已经经过其他方法把DLL打包发送给受害者,执行本地加载DLL即可。

   此方法通常需要HeapSpray协助布局内存数据;且需要文件共享服务器存放恶意DLL;只工作于64位系统上的32位应用程序;不适用于Windows 8

 

五.SEHOP(Structured Exception Handling Overwrite Protection)

●原理:

它可作为SEH的扩展,用于检 测SEH是否被覆写。SEHOP的核心特性是用于检测程序栈中的所有SEH结构链表的完整性,特别是对最后一个SHE结构的检测。在最后一个SEH结构中 拥有一个特殊的异常处理函数指针,指向一个位于ntdll中的函数ntdll!FinalExceptHandler()。当我们用 jmp 06 pop pop ret 来覆盖SEH结构后,由于SEH结构链表的完整性遭到破坏,SEHOP就能检测到异常从而阻止shellcode 的运行

 

●绕过方式:

1.攻击虚函数

2.攻击未开启SEHOP的模块

3.攻击没有开启GS的函数返回值

4.伪造SEH链表

 

六.堆保护

●原理:

(1)SafeUnlink:微软改写了操作双向链表的代码,在卸载free list中的堆块时更加小心

(2)Heap cookie:用于检测堆溢出

(3)元数据加密:微软在Vista以及后续版本中使用了该安全措施,块首中的一些重要数据在保存时,会与一个4字节的随机数进行异或,在使用这些数

 

据的时候需要异或还原,这样就不能直接破坏这些数据了,以达到保护堆的目的

 

●绕过方式:

(1)攻击堆中的存储变量

(2)利用chunk重设大小攻击堆

(3)利用Lookaside表进行堆溢出

 

七.某些逻辑漏洞

●绕过方式:

1.Java的jnlp

是java提供的一种可以通过浏览器直接执行java应用程序的途径,它使你可以直接通过一个网页上的url连接打开一个java应用程序。

这种逻辑漏洞可以绕过EMET

 

2.微软的Microsoft Silverlight,类似于java的jnlp,可以绕过上面的保护方式

 

3.某些VBScript可以绕过EMET(可以远程调用一些文件)

 

 

 

 

 

 

posted @ 2014-09-17 17:40  Bingghost  阅读(3658)  评论(0编辑  收藏  举报