主页 > 知识库 > 服务器 > 网络安全 >

连载:国外高手谈卡巴斯基存隐患(六)

来源: 作者: 发表于:2009-09-29 13:47  点击:
当前操作系统所使用的划分内核/用户的主要原则是:不允许用户层直接访问内核层的内存。这对维持系统稳定十分重要,比如它可以阻止有bug的用户层程序造成内核崩溃,甚至使整个系统崩溃。不幸的是,KAV的程序员们似乎认为这个原则根本不重要。

允许用户层代码访问内核内存


当前操作系统所使用的划分内核/用户的主要原则是:不允许用户层直接访问内核层的内存。这对维持系统稳定十分重要,比如它可以阻止有bug的用户层程序造成内核崩溃,甚至使整个系统崩溃。不幸的是,KAV的程序员们似乎认为这个原则根本不重要。

KAV所执行的不安全操作里最奇怪的地方就在于:它允许用户层直接调用他们内核驱动的一部分(在内核地址空间内!),而不是只加载用户层DLL(或者在目标进程中加载用户层代码)。

该机制似乎是用来在加载DLL时,调查这些DLL的——这种工作本来最好应当由PsSetLoadImageNotifyRoutine来完成。

创建新进程后,KAV给Kernel32.dll打上补丁,这样输出表就会指向所有的DLL——往调用内核层kav的驱动部分的thunk中加载例行程序(例如LoadLibraryA)。另外,KAV还修改它的代码的部分保护以及数据段,以便允许用户层进行读操作。

KAV设置了PsLoadImageNotifyRoutine关联来检测 kernel32.dll的加载,以便确定什么时候给kernel32的输出表打补丁。笔者想知道为什么KAV不只在 PsLoadImageNotifyRoutine中直接工作,而是费尽千辛万苦地通过允许用户层来调用内核层来进行LoadLibrary关联。

在新进程加载图片的时候,KAV会调用CheckInjectCodeForNewProcess函数,并且核查 kernel32是否被加载。如果Kernel32已经加载,那么它将安排APC队列给要执行补丁程序的进程。

.text:F82218B0 ; int __stdcall CheckInjectCodeForNewProcess(wchar_t *,PUCHAR ImageBase)
.text:F82218B0 CheckInjectCodeForNewProcess proc near  ; CODE XREF: KavLoadImageNotifyRoutine+B5p
.text:F82218B0               ; KavDoKernel32Check+41p
.text:F82218B0
.text:F82218B0 arg_0           = dword ptr  4
.text:F82218B0 ImageBase       = dword ptr  8
.text:F82218B0
.text:F82218B0    mov     al, byte_F82282F9
.text:F82218B5    push    esi
.text:F82218B6    test    al, al
.text:F82218B8    push    edi
.text:F82218B9    jz      short loc_F8221936
.text:F82218BB    mov     eax, [esp+8+arg_0]
.text:F82218BF    push    offset aKernel32_dll ; "kernel32.dll"
.text:F82218C4    push    eax             ; wchar_t *
.text:F82218C5    call    ds:_wcsicmp
.text:F82218CB    add     esp, 8
.text:F82218CE    test    eax, eax
.text:F82218D0    jnz     short loc_F8221936
.text:F82218D2    mov     al, g_FoundKernel32Exports
.text:F82218D7    mov     edi, [esp+8+ImageBase]
.text:F82218DB    test    al, al
.text:F82218DD    jnz     short KavInitializePatchApcLabel
.text:F82218DF    push    edi
.text:F82218E0    call    KavCheckFindKernel32Exports
.text:F82218E5    test    al, al
.text:F82218E7    jz      short loc_F8221936
.text:F82218E9
.text:F82218E9 KavInitializePatchApcLabel:             ; CODE XREF: CheckInjectCodeForNewProcess+2Dj
.text:F82218E9    push    '3SeB'          ; Tag
.text:F82218EE    push    30h             ; NumberOfBytes
.text:F82218F0    push    0               ; PoolType
.text:F82218F2    call    ds:ExAllocatePoolWithTag
.text:F82218F8    mov     esi, eax
.text:F82218FA    test    esi, esi
.text:F82218FC    jz      short loc_F8221936
.text:F82218FE    push    edi
.text:F82218FF    push    0
.text:F8221901    push    offset KavPatchNewProcessApcRoutine
.text:F8221906    push    offset loc_F82218A0
.text:F822190B    push    offset loc_F8221890
.text:F8221910    push    0
.text:F8221912    call    KeGetCurrentThread
.text:F8221917    push    eax
.text:F8221918    push    esi
.text:F8221919    call    KeInitializeApc
.text:F822191E    push    0
.text:F8221920    push    0
.text:F8221922    push    0
.text:F8221924    push    esi
.text:F8221925    call    KeInsertQueueApc
.text:F822192B    test    al, al
.text:F822192D    jnz     short loc_F822193D
.text:F822192F    push    esi             ; P
.text:F8221930    call    ds:ExFreePool
.text:F8221936
.text:F8221936 loc_F8221936:              ; CODE XREF: CheckInjectCodeForNewProcess+9j
.text:F8221936               ; CheckInjectCodeForNewProcess+20j ...
.text:F8221936    pop     edi
.text:F8221937    xor     al, al
.text:F8221939    pop     esi
.text:F822193A    retn    8
.text:F822193D ; ---------------------------------------------------------------------------
.text:F822193D
.text:F822193D loc_F822193D:              ; CODE XREF: CheckInjectCodeForNewProcess+7Dj
.text:F822193D    pop     edi
.text:F822193E    mov     al, 1
.text:F8221940    pop     esi
.text:F8221941    retn    8

APC例行程序本身给kernel32的输出表打了补丁(并且生成thunk来调用内核层)并调整KAV的驱动镜像的PTE属性,以便允许用户层访问。

.text:F8221810 KavPatchNewProcessApcRoutine proc near  ; DATA XREF: CheckInjectCodeForNewProcess+51o
.text:F8221810
.text:F8221810 var_8           = dword ptr -8
.text:F8221810 var_4           = dword ptr -4
.text:F8221810 ImageBase       = dword ptr  8
.text:F8221810
.text:F8221810    push    ebp
.text:F8221811    mov     ebp, esp
.text:F8221813    sub     esp, 8
.text:F8221816    mov     eax, [ebp+ImageBase]
.text:F8221819    push    esi
.text:F822181A    push    eax             ; ImageBase
.text:F822181B    call    KavPatchImageForNewProcess
.text:F8221820    mov     esi, dword_F8230518
.text:F8221826    mov     eax, dword_F823051C
.text:F822182B    and     esi, 0FFFFF000h
.text:F8221831    cmp     esi, eax
.text:F8221833    mov     [ebp+ImageBase], esi
.text:F8221836    jnb     short loc_F8221883
.text:F8221838
.text:F8221838 loc_F8221838:              ; CODE XREF: KavPatchNewProcessApcRoutine+71j
.text:F8221838    push    esi
.text:F8221839    call    KavPageTranslation0
.text:F822183F    push    esi
.text:F8221840    mov     [ebp+var_8], eax
.text:F8221843    call    KavPageTranslation1
.text:F8221849    mov     [ebp+var_4], eax
.text:F822184C    mov     eax, [ebp+var_8]
.text:F822184F    lock or dword ptr [eax], 4
.text:F8221853    lock and dword ptr [eax], 0FFFFFEFFh
.text:F822185A    mov     eax, [ebp+var_4]
.text:F822185D    invlpg  byte ptr [eax]
.text:F8221860    lock or dword ptr [eax], 4
.text:F8221864    lock and dword ptr [eax], 0FFFFFEFDh
.text:F822186B    mov     eax, [ebp+ImageBase]
.text:F822186E    invlpg  byte ptr [eax]
.text:F8221871    mov     eax, dword_F823051C
.text:F8221876    add     esi, 1000h
.text:F822187C    cmp     esi, eax
.text:F822187E    mov     [ebp+ImageBase], esi
.text:F8221881    jb      short loc_F8221838
.text:F8221883
.text:F8221883 loc_F8221883:              ; CODE XREF: KavPatchNewProcessApcRoutine+26j
.text:F8221883    pop     esi
.text:F8221884    mov     esp, ebp
.text:F8221886    pop     ebp
.text:F8221887    retn    0Ch
.text:F8221887 KavPatchNewProcessApcRoutine endp

.text:F8221750 ; int __stdcall KavPatchImageForNewProcess(PUCHAR ImageBase)
.text:F8221750 KavPatchImageForNewProcess proc near    ; CODE XREF: KavPatchNewProcessApcRoutine+Bp
.text:F8221750
.text:F8221750 ImageBase       = dword ptr  8
.text:F8221750
.text:F8221750    push    ebx
.text:F8221751    call    ds:KeEnterCriticalRegion
.text:F8221757    mov     eax, dword_F82282F4
.text:F822175C    push    1               ; Wait
.text:F822175E    push    eax             ; Resource
.text:F822175F    call    ds:ExAcquireResourceExclusiveLite
.text:F8221765    push    1
.text:F8221767    call    KavSetPageAttributes1
.text:F822176C    mov     ecx, [esp+ImageBase]
.text:F8221770    push    ecx             ; ImageBase
.text:F8221771    call    KavPatchImage
.text:F8221776    push    0
.text:F8221778    mov     bl, al
.text:F822177A    call    KavSetPageAttributes1
.text:F822177F    mov     ecx, dword_F82282F4 ; Resource
.text:F8221785    call    ds:ExReleaseResourceLite
.text:F822178B    call    ds:KeLeaveCriticalRegion
.text:F8221791    mov     al, bl
.text:F8221793    pop     ebx
.text:F8221794    retn    4
.text:F8221794 KavPatchImageForNewProcess endp

    有帮助
    (31)
    34.1%
    没帮助
    (60)
    65.9%
  • 上一篇:没有了
  • 下一篇:连载:国外高手谈卡巴斯基存隐患(完)