==Phrack Inc.==
Volume 0x0b, Issue 0x3e, Phile #0x06 of 0x10
|=---------------=[ Kernel-mode backdoors for Windows NT ]=--------------=| |=-----------------------------------------------------------------------=| |=-----------------=[ firew0rker <firew0rker@nteam.ru> ]=----------------=| |=----------------=[ the nobodies <http://www.nteam.ru> ]=---------------=|
--[ Table of contents
1 - PREFACE
2 - OVERVIEW OF EXISTING KERNEL-MODE BACKDOORS FOR WINDOWS NT 2.1 - NTROOTKIT 2.2 - HE4HOOK 2.3 - SLANRET (IERK, BACKDOOR-ALI)
3 - OBSCURITY ON DISK, IN REGISTRY AND IN MEMORY
4 - MY VARIANT: THORNY PATH 4.1 - SHELL 4.2 - ACTIVATION AND COMMUNICATION WITH REMOTE CLIENT 4.3 - OBSCURITY ON DISK
5 - CONCLUSION 6 - EPILOGUE 7 - LIST OF USED SOURCES 8 - FILES
--[ 1 - Preface
This article is intended for those who know the architecture of the Windows NT kernel and the principles of operation of NT drivers. This article examines issues involved in the development of kernel-mode tools for stealthy remote administration of Windows NT.
Recently there has been a tendency of extending the use of Windows NT (2000, XP, 2003) from it's classical stronghold as home and office OS to servers. At the same time, the outdated Windows 9x family is replaced by the NT family. Because of this it should be evident that remote administration tools (backdoors) and unnoticeable access tools (rootkits) for the NT family have a certain value. Most of the published utilities work in user-mode and can thus be detected by Antivirus tools or by manual inspection.
It's quite another matter those works in kernel-mode: They can hide from any user-mode program. Antivirus software will have to suplly kernel- mode components in order to detect a kernel-mode-backdoor. Software exists that protects against such backdoors (such as IPD, "Integrity Protection Driver"), but it's use is not widely spread. Kernel mode backdoors are not as widely used as they could be due to their relative complexity in comp- arison with user-mode backdoors.
--[ 2 - Overview of existing Kernel-Mode backdoors for Windows NT
This section briefly reviews existing kernel-mode backdoors for Windows NT.
----[ 2.1 - Ntrootkit
Ntrootkit (c) by Greg Hoglund and a team of free developers [1] is a device driver for Windows NT 4.0 and 2000. It's possibilities (implemented and potential):
- Receiving commands from a remote client. The rk_packet module contains a simplified IP-stack, which uses free IP-address from the subnet where the host on which Ntrootkit has been installed is situated.
It's MAC and IP addresses are hardcoded in the source. Connection with the rootkit at that IP is carried out via a TCP connection to any port. The available commands in rk_command.c are:
ps - list processes help - self explainatory buffertest, echo and debugint - for debugging purpose hidedir - hide directory/file hideproc - hide process(es) sniffkeys - keyboard spy
There are also imcomplete pieces of code: Execute commands received via a covert channel and starting a Win32-process from a driver (a hard and complicated task).
- Encrypt all traffic using Schneier's Blowfish algorithm: rk_blowfish.c is present, but not (yet ?) used
- Self-defense (rk_defense.c) - hide protected objects (in this case: registry keys), identified by the string "_root_"; redirect launched processes.
The hiding of processes, directories and files as implemented in rk_ioman.c is done through hooking the following functions:
NtCreateFile ZwOpenFile ZwQueryDirectoryFile ZwOpenKey ZwQueryKey ZwQueryValueKey ZwEnumerateValueKey ZwEnumerateKey ZwSetValueKey ZwCreateKey
The way to detect this rootkit:
Make direct request to filesystem driver, send IRP to it. There is one more module that hooks file handling: rk_files.c, adopted from filemon, but it is not used.
- Starting processes: An unfinished implementation of it can be found in rk_command.c, another one (which is almost complete and good) is in rk_exec.c
The implementation suffers from the fact that Zw* functions which are normally unavailable to drivers directly are called through the system call interface (int 0x2E), leading to problems with different versions of the NT family as system call numbers change.
It seems like the work on Ntrootkit is very loosely coordinated: every developer does what (s)he considers needed or urgent. Ntrootkit does not achieve complete (or sufficient) invisibility. It creates device named "Ntroot", visible from User-Mode.
When using Ntrootkit for anything practical, one will need some means of interaction with the rootkitted system. Shortly: There will be the need for some sort of shell. Ntrootkit itself can not give out a shell directly, although it can start a process -- the downside is that the I/O of that process can not be redirected. One is thus forced to start something like netcat. It's process can be hidden, but it's TCP-connection will be visible. The missing redirection of I/O is a big drawback.
However, Ntrootkit development is still in progress, and it will probably become a fully-functional tool for complete and stealthy remote administration.
----[ 2.2 - He4Hook
This description is based on [2]. The filesystem access was hooked via two different methods in the versions up to and including 2.15b6. Only one of it works at one time, and in versions after 2.15b6 the first method was removed.
Method A: hook kernel syscalls: ===============================
ZwCreateFile, ZwOpenFile - driver version 1.12 and from 1.17 to 2.15beta6 IoCreateFile - from 1.13 to 2.15beta6 ZwQueryDirectoryFile, ZwClose - before 2.15beta6
Almost all these exported functions (Zw*) have the following function body: mov eax, NumberFunction lea edx, [esp+04h] int 2eh ; Syscall interface
The "NumberFunction" is the number of the called function in the syscalls table (which itself can be accessed via the global variable KeServiceDescriptorTable). This variable points to following structure:
typedef struct SystemServiceDescriptorTable { SSD SystemServiceDescriptors[4]; } SSDT, *LPSSDT;
Other structures:
typedef VOID *SSTAT[]; typedef unsigned char SSTPT[]; typedef SSTAT *LPSSTAT; typedef SSTPT *LPSSTPT;
typedef struct SystemServiceDescriptor { LPSSTAT lpSystemServiceTableAddressTable; ULONG dwFirstServiceIndex; ULONG dwSystemServiceTableNumEntries; LPSSTPT lpSystemServiceTableParameterTable; } SSD, *LPSSD;
The DescriptorTable pointed to by KeServiceDescriptorTable is only accessible from kernel mode. In User-Mode, there is something called KeServiceDescriptorTableShadow -- unfortunately it is not exported.
Base services are in
KeServiceDescriptorTable->SystemServiceDescriptors[0] KeServiceDescriptorTableShadow->SystemServiceDescriptors[0]
KernelMode GUI services are in KeServiceDescriptorTableShadow->SystemServiceDescriptors[1]
Other elements of that tables were free at moment when [2] was written, in all versions up to WinNt4(SP3-6) and Win2k build 2195. Each element of the table is a SSID structure, which contains the following data:
lpSystemServiceTableAddressTable - A pointer to an array of addresses of functions that will be called if a matching syscall is called
dwFirstServiceIndex - Start index for the first function
dwSystemServiceTableNumEntries - Number of services in table
lpSystemServiceTableParameterTable - An array of bytes specifying the number of bytes from the stack that will be passed through
In order to hook a system call, He4HookInv replaces the address stored in KeServiceDescriptorTable->SystemServiceDescriptos[0].lpSystemServiceTableAddressTableIn with a pointer to it's own table.
One can interface with He4HookInv by adding your own services to the system call tables. He4HookInv updates both tables:
- KeServiceDescriptorTable - KeServiceDescriptorTableShadow.
Otherwise, if it updated only KeServiceDescriptorTable, new services would be unavailable from UserMode. To locate KeServiceDescriptorTable- Shadow the following technique is used:
The function KeAddSystemServiceTable can be used to add services to the kernel. It can add services to both tables. Taking into account that its 0-th descriptor is identical, it's possible, by scanning KeAddSystemServiceTable function's code, to find the address of the shadow table. You can see how it is done in file He4HookInv.c, function FindShadowTable(void).
If this method fails for some reason, a hardcoded address is taken (KeServiceDescriptorTable-0x230) as location of the shadow table. This address has not changed since WinNT Sp3. Another problem is the search for the correct index into the function address array. As almost all Zw* functions have an identical first instruction (mov eax, NumberFunction), one can get a pointer to the function number easily by adding one byte to the address exported by ntoskrnl.exe
Method B: (for driver versions 2.11 and higher) =============================================== [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >> |