Uninformed: Informative Information for the Uninformed

Vol 4» 2006.Jun


Patching system services at runtime

Although KAV appears to use a filesystem filter, the standard Windows mechanism for intercepting accesses to files (specifically designed for applications like anti-virus software), the implementors also used a series of API-level function hooks to intercept various file accesses. Performing function hooking in kernel mode is a dangerous proposition; one must be very careful to fully validate all parameters if a function could be called from user mode (otherwise system security could be compromised by a malicious unprivileged program). Additionally, it is generally not safe to remove code hooks in kernel mode as it is difficult to prove that no threads will be running a particular code region in order to unhook without risking bringing down the system. KAV also hooks several other system services in a misguided attempt to "protect" its processes from debuggers and process termination.

Unfortunately, the KAV programmers did not properly validate parameters passed to hooked system calls, thus leading to an opening of holes that, at the very least, allow unprivileged user mode programs to bring down the system. Some of these holes may even allow local privilege escalation (though the author has not spent the time necessary to prove whether such is possible).

KAV hooks the following system services (easily discoverable in WinDbg by comparing nt!KeServiceDescriptorTableShadow on a system with KAV loaded with a clean system):

kd> dps poi ( nt!KeServiceDescriptorTableShadow ) l dwo ( nt!KeServiceDescriptorTableShadow + 8 )
8191c9c8  805862de nt!NtAcceptConnectPort
8191c9cc  8056fded nt!NtAccessCheck
...
8191ca2c  f823fd00 klif!KavNtClose
...
8191ca84  f823fa20 klif!KavNtCreateProcess
8191ca88  f823fb90 klif!KavNtCreateProcessEx
8191ca8c  80647b59 nt!NtCreateProfile
8191ca90  f823fe40 klif!KavNtCreateSection
8191ca94  805747cf nt!NtCreateSemaphore
8191ca98  8059d4db nt!NtCreateSymbolicLinkObject
8191ca9c  f8240630 klif!KavNtCreateThread
8191caa0  8059a849 nt!NtCreateTimer
...
8191cbb0  f823f7b0 klif!KavNtOpenProcess
...
8191cc24  f82402f0 klif!KavNtQueryInformationFile
...
8191cc7c  f8240430 klif!KavNtQuerySystemInformation
...
8191cd00  f82405e0 klif!KavNtResumeThread
...
8191cd58  f82421f0 klif!KavNtSetInformationProcess
...
8191cdc0  f8240590 klif!KavNtSuspendThread
...
8191cdcc  f82401c0 klif!KavNtTerminateProcess

Additionally, KAV attempts to create several entirely new system services as a shortcut for calling kernel mode by patching the service descriptor table. This is certainly not the preferred mechanism to allow a user mode program to communicate with a driver; the programmers should have used the conventional IOCTL interface which avoids the pitfalls of patching kernel structures at runtime and having to deal with other inconveniences such as system service ordinals changing from one OS release to another.