Improper Validation of User-mode Pointers

2006-06-15T00:00:00
ID SECURITYVULNS:DOC:13194
Type securityvulns
Reporter Securityvulns
Modified 2006-06-15T00:00:00

Description

Improper Validation of User-mode Pointers

Many of the hooks that KAV installs (and even the custom system services) suffer from flaws that are detrimental to the operation of the system. For instance, KAV's modified NtOpenProcess attempts to determine if a user address is valid by comparing it to the hardcoded value 0x7FFF0000. On most x86 Windows systems, this address is below the highest user address (typically 0x7FFEFFFF). However, hardcoding the size of the user address space is not a very good idea. For example, there is a boot parameter `/3GB' that can be set in boot.ini in order to change the default address space split of 2GB kernel and 2GB user to 1GB kernel and 3GB user. If a system with KAV is configured with /3GB, it is expected that anything that calls NtOpenProcess (such as the win32 OpenProcess) may randomly fail if parameter addresses are located above the first 2GB of the user address space:

.text:F82237B0 ; NTSTATUS __stdcall KavNtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) .text:F82237B0 KavNtOpenProcess proc near ; DATA XREF: sub_F82249D0+BFo . . . .text:F8223800 cmp eax, 7FFF0000h ; eax = ClientId .text:F8223805 jbe short loc_F822380D .text:F8223807 .text:F8223807 loc_F8223807: ; CODE XREF: KavNtOpenProcess+4Ej .text:F8223807 call ds:ExRaiseAccessViolation

The proper way to perform this validation would have been to use the documented ProbeForRead function with a SEH frame, which will automatically raise an access violation if the address is not a valid user address.

Additionally, many of KAV's custom system services do not properly validate user mode pointer arguments, which could be used to bring down the system:

.text:F8222BE0 ; int __stdcall KAVService10(int,PVOID OutputBuffer,int) .text:F8222BE0 KAVService10 proc near ; DATA XREF: .data:F8227D14o .text:F8222BE0 .text:F8222BE0 arg_0 = dword ptr 4 .text:F8222BE0 OutputBuffer = dword ptr 8 .text:F8222BE0 arg_8 = dword ptr 0Ch .text:F8222BE0 .text:F8222BE0 mov edx, [esp+OutputBuffer] .text:F8222BE4 push esi .text:F8222BE5 mov esi, [esp+4+arg_8] .text:F8222BE9 lea ecx, [esp+4+arg_8] .text:F8222BED push ecx ; int .text:F8222BEE mov eax, [esi] ; Unvalidated user mode pointer access .text:F8222BF0 mov [esp+8+arg_8], eax .text:F8222BF4 push eax ; OutputBufferLength .text:F8222BF5 mov eax, [esp+0Ch+arg_0] .text:F8222BF9 push edx ; OutputBuffer .text:F8222BFA push eax ; int .text:F8222BFB call sub_F821F9A0 ; This routine internally assumes that ; all pointer parameters given are valid. .text:F8222C00 mov edx, [esi] .text:F8222C02 mov ecx, [esp+4+arg_8] .text:F8222C06 cmp ecx, edx .text:F8222C08 jbe short loc_F8222C13 .text:F8222C0A mov eax, 0C0000173h .text:F8222C0F pop esi .text:F8222C10 retn 0Ch .text:F8222C13 ; --------------------------------------------------------------------------- .text:F8222C13 .text:F8222C13 loc_F8222C13: ; CODE XREF: KAVService10+28j .text:F8222C13 mov [esi], ecx .text:F8222C15 pop esi .text:F8222C16 retn 0Ch .text:F8222C16 KAVService10 endp

.text:F8222C20 KAVService11 proc near ; DATA XREF: .data:F8227D18o .text:F8222C20 .text:F8222C20 arg_0 = dword ptr 4 .text:F8222C20 arg_4 = dword ptr 8 .text:F8222C20 arg_8 = dword ptr 0Ch .text:F8222C20 .text:F8222C20 mov edx, [esp+arg_4] .text:F8222C24 push esi .text:F8222C25 mov esi, [esp+4+arg_8] .text:F8222C29 lea ecx, [esp+4+arg_8] .text:F8222C2D push ecx .text:F8222C2E mov eax, [esi] ; Unvalidated user mode pointer access .text:F8222C30 mov [esp+8+arg_8], eax .text:F8222C34 push eax .text:F8222C35 mov eax, [esp+0Ch+arg_0] .text:F8222C39 push edx .text:F8222C3A push eax .text:F8222C3B call sub_F8214CE0 ; This routine internally assumes ; that all pointer parameters given are valid. .text:F8222C40 test eax, eax .text:F8222C42 jnz short loc_F8222C59 .text:F8222C44 mov ecx, [esp+4+arg_8] .text:F8222C48 mov edx, [esi] .text:F8222C4A cmp ecx, edx .text:F8222C4C jbe short loc_F8222C57 .text:F8222C4E mov eax, STATUS_INVALID_BLOCK_LENGTH .text:F8222C53 pop esi .text:F8222C54 retn 0Ch .text:F8222C57 ; --------------------------------------------------------------------------- .text:F8222C57 .text:F8222C57 loc_F8222C57: ; CODE XREF: KAVService11+2Cj .text:F8222C57 mov [esi], ecx .text:F8222C59 .text:F8222C59 loc_F8222C59: ; CODE XREF: KAVService11+22j .text:F8222C59 pop esi .text:F8222C5A retn 0Ch .text:F8222C5A KAVService11 endp