您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页卡巴斯基存在的隐患之详解

卡巴斯基存在的隐患之详解

来源:化拓教育网
允许用户层代码访问内核内存

当前操作系统所使用的划分内核/用户的主要原则是:不允许用户层直接访问内核层的内存。这对维持系统稳定十分重要,比如它可以阻止有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_F82210 .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:F82218 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

顶一下 (30) 33.70% 踩一下 (59) 66.30%

解决方案

KAV的杀毒软件依靠诸多不安全内核层的黑客程序,从而将系统稳定性置于危险中。想要解决这个问题,首先KAV需要去掉不安全的内核层黑客程序,比如给非输出函数打补丁或者不加验证地关联系统服务等等。

KAV使用钩子函数或者其他不安全措施的那些操作也可以通过有记录的并且安全的 API以及例行程序来实现,这些都是在Windows 设备驱动工具组(DDK)和可安装文件系统工具组(IFS kit)中详细说明过的。KAV的程序员有必要花时间理解关于如何使用有记录的方法在系统内核进行操作,而不是用字面上的hack-and-slash的方法,致使系统有崩溃或者甚至扩大范围的危险。

KAV所倚仗的很多不安全操作都被x的补丁防御功能拦截了,这使得KAV更难发布针对位系统的杀毒软件了(由于计算机开始支持x,有的默认的就是x的操作系统,于是X版的杀毒软件也变得尤为重要)。32位的内核驱动无法在位的系统中使用,因此KAV需要将它的驱动移植到x上并且解决补丁防御功能的问题。另外,终端用户使用的是单核计算机的假设很快就会不成立了,现在很多系统都支持超线程或者多核。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务