能力值:
( LV12,RANK:370 )
|
-
-
2 楼
丁页你。。。坐了一盘沙发
|
能力值:
(RANK:1130 )
|
-
-
3 楼
看不懂啊,西裤哥坐沙发教教我
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
|
能力值:
( LV9,RANK:1210 )
|
-
-
5 楼
嗯,是我写得太潦草了,再加几句说明:
跟OllyBone要做的事情一样,只是用的PTE的NX位,需要打开PAE。一般机器的DEP都是开着的,就在PAE下。
但做的标记会被清除掉,所以挂KeInterlockedSwapPte,在这把标记再置回去。大概就这意思。
deroko以前的DOER,也不好用。后来的xTracer更好,但我没读过。
|
能力值:
(RANK:350 )
|
-
-
6 楼
SM大叔的帖子看不懂
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
看的头晕 虚心学习一下 楼主您辛苦了。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
学习中。。。。。
|
能力值:
(RANK:350 )
|
-
-
9 楼
softworm的帖子是要收藏的
|
能力值:
( LV9,RANK:250 )
|
-
-
10 楼
看不懂的说啊...
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
一点看不懂,哎,差距真大啊。。
|
能力值:
(RANK:680 )
|
-
-
12 楼
强帖, 收藏了~~
|
能力值:
( LV12,RANK:470 )
|
-
-
13 楼
跟着膜拜 看不懂。。学习
google了一个参考资料 http://www.flyingkisser.com/articledisplay.php?aid=6
有关DEP(数据执行保护)的一点研究 2006-11-02 flyingkisser 国外在这个方面的研究已经比较成熟了,04年DEP刚出来没多久俄罗斯某黑客组织就宣称这个东西他们已经可以攻破 后来,美国的nologin组织也发了一篇paper,专门说如何绕过硬件DEP保护的。 而国内在此方面的讨论好像不多,似乎焦点上有人讨论过。 我这里主要说的是软DEP,非硬件DEP,所以深度上估计明显打了折扣。 不过没关系,软DEP讨论的好像真不多(或者是我错过了?),我就在此费话几句吧。 下面从以下4个问题开始进入这个话题。 1.什么是DEP 2.DEP能保护什么? 3.可以绕过DEP吗? 4.DEP在内核中到底是如何实现的?
1.什么是DEP DEP,全称是Data Excution Protection,中名叫数据执行保护,是xp+sp2,win2k03+sp1中加入的对内存的一种保护, 用来防止恶意程序对系统的攻击,如溢出。 现在只有两种设置方式, 一是只为系统关键进程和服务提供DEP保护,这也是默认选项 二是为所有程序和服务提供DEP保护,除去用户手动指定的程序 其设置在 我的电脑--属性--高级--性能 设置--数据执行保护
2.DEP能保护什么? 我觉得DEP就是专门为反溢出设计的,当然这么说有点狭隘了点,毕竟这种机制完善了cpu的内存管理机制。虽然 我觉得为每一个指令都进行内存页属性的检测会不会有点太费资源了。 一句话,DEP可以使指定的内存页不具有可执行属性。 这样一来,如果指定栈所在的内存页不可执行,那么,当我们要栈上溢出时,我们的Shellcode将难以被执行。 所以,DEP保护的就是内存,保护指定的内存上的代码不能被执行,这样就可以达到反溢出的目的。 当然,这是微软的一厢情愿罢了。因为越过这个限制也并不是一件难事。
3.可以绕过DE吗?如果可以,如何绕过呢? 答案是肯定的。可以绕过,即使是硬件上的DEP保护。 具体方法也很容易想到。有一个API,改变指定内存页的属性的,VirtualProtect(),当然,还有其它的API,如 VirtualProtectEx(),ZwProtectVirtulMemory(),不过都是封闭在VirtualProtect()中。 所以,我们溢出的时候,把返回地址设计为这个API的地址,再精心构造一个栈为调用这个API的栈,就可以 改变当前栈的内存页的属性,使其从"不可执行"变成"可执行". 这个过程的示例如下面的一段代码 _test proc ;push 04 ;invoke VirtualProtect,esp,30h,PAGE_EXECUTE_READWRITE,esp ;pop eax mov dword ptr [esp+18h],4 mov eax,esp add eax,18h mov dword ptr [esp+14h],eax;lpOldProtection mov dword ptr [esp+10h],40h;dwNewProtection mov dword ptr [esp+0ch],30h;dwRegionSize mov dword ptr [esp+8],esp;dwStartAddress mov dword ptr [esp],VirtualProtect;func addr mov eax,esp add eax,1ch mov dword ptr [esp+4],eax;return address from VirtualProtect mov dword ptr [esp+1ch],90909090h;our shellcode ret _test endp
4.DEP在内核中到底是如何实现的? 这个问题我曾经费不了少时间去找答案,从内存操作的API上来看, 有标准内存管理API,虚拟内存管理API,堆管理API,内存映射文件API 从内存管理的结构上来看,有VAD,有PFN,有PTE,PDE,有段 一开始我认为windows可能会在任何一个层面上做文章,可能是VAD,也可能是PFN,也可能是PTE 并且我认为VAD的可能性比较大,因为PTE没有相关的bit位表示此页有没有可执行属性。PFN也没有。 VAD倒是有相关的位表示页的可执行属性。 经过一点点的测试和排除,发现VAD与此并没有关系,用VirtualProtect()改变页的属性时,此页对应 的VAD的flag位竟然毫无变化。 那么只剩下PFN和PTE了,发现这个API调用前后,PFN的restore pte这个字段有变化,PTE的低双字却 没有一点变化,高双字我时候我没有关心,我一直认为高双字是用于寻址4G以外的物理内存地址的。 然后我手动把PFN的restore pte改变成上面提到的API改成的值,但是结果却让人失望,我拷入shellcode 的页还是不可执行。 尽管这时,我还是没有意识到PTE的高双字发生的变化,并为此付出了代价,那就是二夜一天的对VirtualProtect() 相关API的反汇编。 VirtualProtect()调用了VirtualProtectEx() VirtualProtectEx()调用了ZwProtectVirtualMemory() ZwProtectVirtualMemory()通过sysenter进入内核,EAX中存放的服务号是0x89,对应的服务是NtProtecVirtualMemory() NtProtectVirtualMemory()又调用了MiProtectVirtualMemory() 在MiProtectVirtualMemory()内部,计算出要改变其属性的内存页的PTE的地址,新的属性,然后调用 MiFlushTbAndCapture()改变PTE的属性,但是我当时也只是看到把PTE的属性从067变成了027,和可执行属性还是 没有关系,然后我再深入到MiFlushTbAndCapture()中,发现它主要又是调用KeFlushSingleTb()来改变指定PTE 的属性的,深入到KeFlushSingleTb()内部,它主要是调用KeInterlockedSwapPte()来改变指定PTE的属性。 而KeInterlockedSwapPte()的内部是比较简单的,来看看它的反汇编代码: nt!KeInterlockedSwapPte: 80541c08 53 push ebx 80541c09 56 push esi 80541c0a 8b5c2410 mov ebx,dword ptr [esp+10h] ;ebx=新的PTE值所在变量的地址 80541c0e 8b74240c mov esi,dword ptr [esp+0Ch] ;esi=PTE地址 80541c12 8b4b04 mov ecx,dword ptr [ebx+4] ;ecx=新PTE值高双字 80541c15 8b1b mov ebx,dword ptr [ebx] ;ebx=新PTE值低双字 80541c17 8b5604 mov edx,dword ptr [esi+4] ;edx=旧PTE值高双字 80541c1a 8b06 mov eax,dword ptr [esi] ;eax=旧PTE值低双字 80541c1c 0fc70e cmpxchg8b qword ptr [esi] 看到关键点了吧,就是一个cmpxch8b指令,这个指令是干什么的呢? 执行的操作:edx,eax与DST相比较 如果 (edx,eax)=(dst) 则 ZF=1,(dst)<-(ecx,ebx) 否则 ZF=0,(edx,eax)<-dst 很简单,如果新的PTE属性和旧的不等,把PTE属性设置为新的属性。如果相等,则实际上等于不进行操作。 从这里我才发现,他把PTE的高双字设置为0了,以前的值是0x80000000. 所以,DEP是通过PTE的高双字的最高bit即bit63来实现的,这个位置位了,表示此页不可执行。没有置位, 表示此页可以执行。而win2k下面的页目录和页表项只有32个bit,所以不可能提供DEP的这个保护位,因此 DEP只有在64bit的PTE上才能实现。而只有cr4的bit5即PAE启用的时候,PTE才为64bit。 所以,可以这么说吧,intel的奔腾CPU是早就有PAE属性位的,可以支持64位的页表项,而windows系统 只有win2k的某个版本,winxp和win2003的某个server pack版本的内核才支持64的页表项。 不管怎样,PTE的第63位控制着页的可执行属性,我后来查了IA,在IA的修正说明中,才提到这一点,并 把这个位叫做EXB,却对此位的作用一字为提。 但是我们是不能在ring3下操作PTE的,所以,绕过DEP还是得用return-to-lib的经典方式返回到VirtualProtect()来改变当前栈的属性。
|
能力值:
( LV9,RANK:250 )
|
-
-
14 楼
标记一下 方便日后膜拜 可能再出现个插件不?或者被SOD吸收?
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
__asm {
mov eax, Page
mov eax, [eax]
}
请问这里的[eax]送给eax,起到什么作用?
|
能力值:
(RANK:210 )
|
-
-
16 楼
只能膜拜
无法学习
|
能力值:
( LV6,RANK:90 )
|
-
-
17 楼
[QUOTE=bozer;655639]__asm {
mov eax, Page
mov eax, [eax]
}
请问这里的[eax]送给eax,起到什么作用?[/QUOTE]
测试是否有效指针~
|