background image
rootkit--that conceals any file, process, or registry key whose name begins with the prefix
$sys$
. The
result is that XCP's main installation directory, and most of its registry keys, files, and processes, become
invisible to normal programs and administration tools.
The rootkit is a kernel-level driver named
$sys$aries
that is set to automatically load early in the boot
process. When the rootkit starts, it hooks several Windows system calls by modifying the system service
dispatch table (the kernel's
KeServiceDescriptorTable
structure) which is an array of pointers to
the kernel functions that implement basic system calls. The rootkit changes five of these addresses to point
to functions within the rootkit, so that calls to the patched system calls are handled by the rootkit rather than
the original kernel function. The rootkit calls the real kernel function with the same parameters and filters
the results before returning them to the application.
The system calls intercepted by the rootkit are:
1.
NtQueryDirectoryFile
­ This function is used to list the contents of a directory; the rootkit ver-
sion filters out directory entries that begin with
$sys$
, rendering such files and directories invisible
to applications.
2.
NtCreateFile
­ This call is used for creating and opening files. The rootkit version returns an
invalid filename error when programs attempt to open existing files with names starting with
$sys$
,
protecting XCP's files from reading or writing by other programs.
3.
NtQuerySystemInformation
­ One use of this function is to obtain a list of running processes.
The rootkit filters out any processes with names prefixed by
$sys$
, making them invisible to other
applications.
4.
NtEnumerateKey
­ This function returns a list of the subkeys of a registry key. The rootkit fil-
ters the results to remove subkeys with names starting with
$sys$
. Note that it does not conceal
individual fields within the registry ("values" in Windows parlance) with names starting with
$sys$
.
5.
NtOpenKey
­ This function opens a registry key for reading or modifying. The rootkit intercepts this
function call but does not alter its behavior. Its authors may have intended to restrict access to hidden
registry keys in the same way that the hooked
NtQueryDirectoryFile
call restricts access to
hidden files, but they did not ship a working implementation of this behavior.
On intercepting a function call, the rootkit checks the name of the calling process. If the name of
the calling process begins with
$sys$
, the rootkit returns the results of the real kernel function without
alteration so that XCP's own processes have an accurate view of the system.
The XCP rootkit increases users' vulnerability to attack by allowing any software to hide--not just XCP.
Malware authors can exploit the fact that any files, registry keys, or processes with names beginning in
$sys$
will be hidden, thereby saving the trouble of installing their own rootkits. Malware that lacks the
privileges to install its own rootkit can still rely on XCP's rootkit.
Only kernel-level processes can patch the Windows system service dispatch table, and only privileged
users--normally, members of the Administrators or Power Users groups--can install such processes. (XCP
itself requires these privileges to install.) Malicious code running as an unprivileged user can't normally
install a rootkit that intercepts system calls. But if the XCP rootkit is installed, it will hide all programs
that adopt the
$sys$
prefix so that even privileged users will be unable to see them. This vulnerability has
already been exploited by at least two Trojan horses seen in the wild [21, 17].
Another privilege escalation attack facilitated by the XCP rootkit allows an unprivileged application to
crash the system. Russinovich demonstrated this problem using an automated testing program he created
19