Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:13195
HistoryJun 15, 2006 - 12:00 a.m.

Hiding Threads from User-mode

2006-06-1500:00:00
vulners.com
9

Hiding Threads from User-mode

KAV's errors with hooking do not end with NtOpenProcess, however. One of the system services KAV hooks is NtQuerySystemInformation. This routine's behavior is modified to sometimes truncate a thread listing from certain processes when the SystemProcessesAndThreads information class is requested. This is the underlying mechanism for user mode to receive a process and thread listing of all programs running in the system, and in effect, provides a means for KAV to hide threads from user mode. The very fact that this code exists at all in KAV is curious; hiding running code from user mode is typically something that is associated with rootkits and not anti-virus software.

Aside from the potentially abusive behavior of hiding running code, this hook contains several security flaws:

  1. It uses the user mode output buffer from NtQuerySystemInformation after it has been filled by the actual kernel implementation, but it does not guard against a malicious user mode program modifying this buffer or even freeing it. There is no SEH frame wrapping this function, so a user mode program could cause KAV to touch freed memory.

  2. There is no validation of offsets within the returned output buffer to ensure that offsets do not refer to memory outside of the output buffer. This is problematic, because the returned data structure is actually a list of sub-structures that must be walked by adding an offset supplied as part of a particular substructure to the address of that substructure in order to reach the next substructure. Such an offset could be modified by user mode to actually point into kernel memory. Because the hook then sometimes writes data into what it believes is the user mode output buffer, this is an interesting avenue to explore for gaining kernel privileges from an unprivileged user mode function.

.text:F8224430 ; NTSTATUS __stdcall KavNtQuerySystemInformation(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength)
.text:F8224430 KavNtQuerySystemInformation proc near ; DATA XREF: sub_F82249D0+17Bo
.text:F8224430
.text:F8224430 var_10 = dword ptr -10h
.text:F8224430 var_C = dword ptr -0Ch
.text:F8224430 var_8 = dword ptr -8
.text:F8224430 SystemInformationClass= dword ptr 4
.text:F8224430 SystemInformation= dword ptr 8
.text:F8224430 SystemInformationLength= dword ptr 0Ch
.text:F8224430 ReturnLength = dword ptr 10h
.text:F8224430 arg_24 = dword ptr 28h
.text:F8224430
.text:F8224430 mov eax, [esp+ReturnLength]
.text:F8224434 mov ecx, [esp+SystemInformationLength]
.text:F8224438 mov edx, [esp+SystemInformation]
.text:F822443C push ebx
.text:F822443D push ebp
.text:F822443E push esi
.text:F822443F mov esi, [esp+0Ch+SystemInformationClass]
.text:F8224443 push edi
.text:F8224444 push eax
.text:F8224445 push ecx
.text:F8224446 push edx
.text:F8224447 push esi
.text:F8224448 call OrigNtQuerySystemInformation
.text:F822444E mov edi, eax
.text:F8224450 cmp esi, SystemProcessesAndThreadsInformation ;
.text:F8224450 ; Not the process / thread list API?
.text:F8224450 ; Return to caller
.text:F8224453 mov [esp+10h+ReturnLength], edi
.text:F8224457 jnz ret_KavNtQuerySystemInformation
.text:F822445D xor ebx, ebx
.text:F822445F cmp edi, ebx ;
.text:F822445F ; Nothing returned?
.text:F822445F ; Return to caller
.text:F8224461 jl ret_KavNtQuerySystemInformation
.text:F8224467 push ebx
.text:F8224468 push 9
.text:F822446A push 8
.text:F822446C call sub_F8216730
.text:F8224471 test al, al
.text:F8224473 jz ret_KavNtQuerySystemInformation
.text:F8224479 mov ebp, g_KavDriverData
.text:F822447F mov ecx, [ebp+0Ch]
.text:F8224482 lea edx, [ebp+48h]
.text:F8224485 inc ecx
.text:F8224486 mov [ebp+0Ch], ecx
.text:F8224489 mov ecx, ebp
.text:F822448B call ds:ExInterlockedPopEntrySList
.text:F8224491 mov esi, eax
.text:F8224493 cmp esi, ebx
.text:F8224495 jnz short loc_F82244B7
.text:F8224497 mov eax, [ebp+10h]
.text:F822449A mov ecx, [ebp+24h]
.text:F822449D mov edx, [ebp+1Ch]
.text:F82244A0 inc eax
.text:F82244A1 mov [ebp+10h], eax
.text:F82244A4 mov eax, [ebp+20h]
.text:F82244A7 push eax
.text:F82244A8 push ecx
.text:F82244A9 push edx
.text:F82244AA call [ebp+arg_24]
.text:F82244AD mov esi, eax
.text:F82244AF cmp esi, ebx
.text:F82244B1 jz ret_KavNtQuerySystemInformation
.text:F82244B7
.text:F82244B7 loc_F82244B7: ; CODE XREF: KavNtQuerySystemInformation+65j
.text:F82244B7 mov edi, [esp+10h+SystemInformation]
.text:F82244BB mov dword ptr [esi], 8
.text:F82244C1 mov dword ptr [esi+4], 9
.text:F82244C8 mov [esi+8], ebx
.text:F82244CB mov [esi+34h], ebx
.text:F82244CE mov dword ptr [esi+3Ch], 1
.text:F82244D5 mov [esi+10h], bl
.text:F82244D8 mov [esi+30h], ebx
.text:F82244DB mov [esi+0Ch], ebx
.text:F82244DE mov [esi+38h], ebx
.text:F82244E1 mov ebp, 13h
.text:F82244E6
.text:F82244E6 LoopThreadProcesses: ; CODE XREF: KavNtQuerySystemInformation+ECj
.text:F82244E6 mov dword ptr [esi+40h], 4 ;
.text:F82244E6 ; Loop through the returned list of processes and threads.
.text:F82244E6 ; For each process, we shall check to see if it is a
.text:F82244E6 ; special (protected) process. If so, then we might
.text:F82244E6 ; decide to remove its threads from the listing returned
.text:F82244E6 ; by setting the thread count to zero.
.text:F82244ED mov [esi+48h], ebx
.text:F82244F0 mov [esi+44h], ebp
.text:F82244F3 mov eax, [edi+SYSTEM_PROCESSES.ProcessId]
.text:F82244F6 push ebx
.text:F82244F7 push esi
.text:F82244F8 mov [esi+4Ch], eax
.text:F82244FB call KavCheckProcess
.text:F8224500 cmp eax, 7
.text:F8224503 jz short CheckNextThreadProcess
.text:F8224505 cmp eax, 1
.text:F8224508 jz short CheckNextThreadProcess
.text:F822450A cmp eax, ebx
.text:F822450C jz short CheckNextThreadProcess
.text:F822450E mov [edi+SYSTEM_PROCESSES.ThreadCount], ebx ;
; Zero thread count out (hide process threads)
.text:F8224511
.text:F8224511 CheckNextThreadProcess: ; CODE XREF: KavNtQuerySystemInformation+D3j
.text:F8224511 ; KavNtQuerySystemInformation+D8j …
.text:F8224511 mov eax, [edi+SYSTEM_PROCESSES.NextEntryDelta]
.text:F8224513 cmp eax, ebx
.text:F8224515 setz cl
.text:F8224518 add edi, eax
.text:F822451A cmp cl, bl
.text:F822451C jz short LoopThreadProcesses