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

时间:2008-12-14 06:16:22  来源:第二电脑网上收集  作者:

  第二电脑网导读:核会判断作为调用者进行交互的是哪个(通常是系统服务),然后将句柄解析成某个特定对象的指针。所有的对象都共享相同的句柄命名空间。 由于这些不同类型的对象共享着相同的命名空间,系统服务检查句柄的一项任务就是验证这些对象指向的是期望类型。这项工作是由对象管理例行程序bReferenceObjectByHandle完成的,这个例行程序会将句柄解析成对象指针并进...
  正文:

内核对象类型不恰当验证

Windows一系列的“内核对象”暴露了内核的很多特性。这些对象有可能是由用户层通过句柄用户来执行的。句柄是整数值,内核会判断作为调用者进行交互的是哪个(通常是系统服务),然后将句柄解析成某个特定对象的指针。所有的对象都共享相同的句柄命名空间。

由于这些不同类型的对象共享着相同的命名空间,系统服务检查句柄的一项任务就是验证这些对象指向的是期望类型。这项工作是由对象管理例行程序bReferenceObjectByHandle完成的,这个例行程序会将句柄解析成对象指针并进行可选的嵌入类型检查,它是通过把标准对象页头中的类型域与需要验证的进行对照来完成检查的。

由于KAV关联着系统服务,它不可避免地需要处理内核句柄。不幸的是,它并没有正确地进行此类操作。在一些情况下,在使用对象指针前,KAV并不能确定指向某类型对象的句柄。如果错误类型的句柄被传递给了系统服务,那么系统就有可能崩溃。

典型的例子就是KAV的NtResumeThread关联,该关联试图跟踪系统中正在运行的线程的状态。在这个特例中,看起来用户层好像无法通过把错误类型的对象作为返回对象指针而导致系统崩溃。这主要是因为它仅仅是被用作查找表的钥匙,该列表由线程对象指针预先占用了。KAV跟NtSuspendThread相关联也是基于同样的目的,并且这项关联也在验证对象的句柄类型上存在问题。

.text:F82245E0 ; NTSTATUS __stdcall KavNtResumeThread(		HANDLE ThreadHandle,		PULONG PreviousSuspendCount).text:F82245E0 KavNtResumeThread proc near             ; DATA XREF: sub_F82249D0+FBo.text:F82245E0.text:F82245E0 ThreadHandle    = dword ptr  8.text:F82245E0 PreviousSuspendCount= dword ptr  0Ch.text:F82245E0.text:F82245E0    push    esi.text:F82245E1    mov     esi, [esp+ThreadHandle].text:F82245E5    test    esi, esi.text:F82245E7    jz      short loc_F8224620.text:F82245E9    lea     eax, [esp+ThreadHandle] ;.text:F82245E9               ; This should pass an object type here!在这里应当传递对象类型.text:F82245ED    push    0               ; HandleInformation.text:F82245EF    push    eax             ; Object.text:F82245F0    push    0               ; AccessMode.text:F82245F2    push    0               ; ObjectType.text:F82245F4    push    0F0000h         ; DesiredAccess.text:F82245F9    push    esi             ; Handle.text:F82245FA    mov     [esp+18h+ThreadHandle], 0.text:F8224602    call    ds:ObReferenceObjectByHandle.text:F8224608    test    eax, eax.text:F822460A    jl      short loc_F8224620.text:F822460C    mov     ecx, [esp+ThreadHandle].text:F8224610    push    ecx.text:F8224611    call    KavUpdateThreadRunningState.text:F8224616    mov     ecx, [esp+ThreadHandle] ; Object.text:F822461A    call    ds:ObfDereferenceObject.text:F8224620.text:F8224620 loc_F8224620:              ; CODE XREF: KavNtResumeThread+7j.text:F8224620               ; KavNtResumeThread+2Aj.text:F8224620    mov     edx, [esp+PreviousSuspendCount].text:F8224624    push    edx.text:F8224625    push    esi.text:F8224626    call    OrigNtResumeThread.text:F822462C    pop     esi.text:F822462D    retn    8.text:F822462D KavNtResumeThread endp.text:F822462D.text:F8224590 ; NTSTATUS __stdcall KavNtSuspendThread(		HANDLE ThreadHandle,		PULONG PreviousSuspendCount).text:F8224590 sub_F8224590    proc near               ; DATA XREF: sub_F82249D0+113o.text:F8224590.text:F8224590 ThreadHandle    = dword ptr  8.text:F8224590 PreviousSuspendCount= dword ptr  0Ch.text:F8224590.text:F8224590    push    esi.text:F8224591    mov     esi, [esp+ThreadHandle].text:F8224595    test    esi, esi.text:F8224597    jz      short loc_F82245D0.text:F8224599    lea     eax, [esp+ThreadHandle] ;.text:F8224599               ; This should pass an object type here!.text:F822459D    push    0               ; HandleInformation.text:F822459F    push    eax             ; Object.text:F82245A0    push    0               ; AccessMode.text:F82245A2    push    0               ; ObjectType.text:F82245A4    push    0F0000h         ; DesiredAccess.text:F82245A9    push    esi             ; Handle.text:F82245AA    mov     [esp+18h+ThreadHandle], 0.text:F82245B2    call    ds:ObReferenceObjectByHandle.text:F82245B8    test    eax, eax.text:F82245BA    jl      short loc_F82245D0.text:F82245BC    mov     ecx, [esp+ThreadHandle].text:F82245C0    push    ecx.text:F82245C1    call    KavUpdateThreadSuspendedState.text:F82245C6    mov     ecx, [esp+ThreadHandle] ; Object.text:F82245CA    call    ds:ObfDereferenceObject.text:F82245D0.text:F82245D0 loc_F82245D0:              ; CODE XREF: sub_F8224590+7j.text:F82245D0               ; sub_F8224590+2Aj.text:F82245D0    mov     edx, [esp+PreviousSuspendCount].text:F82245D4    push    edx.text:F82245D5    push    esi.text:F82245D6    call    OrigNtSuspendThread.text:F82245DC    pop     esi.text:F82245DD    retn    8.text:F82245DD sub_F8224590    endp.text:F82245DD

但是,并不是所有的KAV关联都这么幸运。KAV安装的NtTerminateProcess钩子会查看函数的进程句柄参数所指向的对象实体,这样就能确定要终止的进程的名称。但是KAV没有验证用户层提供的对象句柄是否是真的指向一个进程对象。 《连载:国外高手谈卡巴斯基存隐患(四)》由第二电脑网原创提供,转载请注明:http://www.002pc.com/master/College/Server/Safe/2008-12-14/6549.html


关键字:

关于《连载:国外高手谈卡巴斯基存隐患(四)》文章的评论

站内搜索: 高级搜索

热门搜索: Windows style 系统 tr IP QQ CPU 安装 function 注册 if td