Rookit Technical Foundation (3)

Source: Internet
Author: User
Tags apc

. Port hiding
Many people check whether they have Trojans or backdoors. They may use some methods to check the ports opened on their own machines to determine whether there is a trojan listener. Some rootkits start to think about how to hide the ports.
The simplest way to enumerate the currently opened port information is to call the allocateandgettcptablefromstack and allocateandgetudptablefromstack functions in the iphlpapi. dll, or the allocateandgettcpextablefromstack and callback functions.
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 method. When a program creates a socket and starts listening, it will have an open handle for it and opened the port. In the system, we enumerate all open handles and send them to a specific buffer using NtDeviceIoControlFile to identify whether the handle is an open port. In this way, we can also provide information about ports. Because there are too many open handles, we only check that the type is File and the name is \ Device \ Tcp or \ Device \ Udp. Only this type and name are allowed to open the port.
Check the code of iphlpapi. dll. These functions call NtDeviceIoControlFile and send it to a specific buffer to obtain the list of all open ports in the system. That is to say, you can hide the port by attaching the NtDeviceIoControlFile function.
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 descriptions of these parameters in theunincluented 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.
Mainly include FileHandle, IoStatusBlock, IoControlCode, IoControlCode, InputBufferLength, OutputBuffer, and OutputBufferLength.
Excerpted from "Let yourself disappear" in the NT operating system.
Also, the technology of port hiding is not mentioned because it is clear in my article, so writing is a waste of space.
Jiurl has also mentioned a method to hide a port and provides code. The document URL is included in the references.
4. Hide the file.
In WINNT, you can find a file in some directories by enumerating all the files in it and all the files in its subdirectories. File enumeration uses 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
);

Descriptions of these parameters in theunincluented Functions-Microsoft Windows NT_2000
FileHandle
HANDLE to File Object opened with FILE_DIRECTORY_FILE option andFILE_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:
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 bereturned.

Restartscan
Used with returnsingleentry parameter. If set, ntquerydirectoryfile continueenumeration after last enumerated element in previous call. If no, returns thefirst entry in directory.

Important parameters related to hidden files are FileHandle, FileInformation, and FileInformationClass.
There are too many related information in FileInformationClass, only four of which are important.
FileDirectoryInformation
FileFullDirectoryInformation
FileBothDirectoryInformation
FileNamesInformation

Structure of the FileDirecoryInformation record for which FileInformation is to be written:

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 to FileInformation. It is important for us to have only three variables in these structure types.
Nextentryoffset is the offset address of the item in this list. The first item is in the address fileinformation + 0, so the second item is in the nextentryoffset where the address is fileinformation + the first item. The nextentryoffset of the last item is 0.
Filename is the full name of the file.
Filenamelength is the object name length.
If we want to hide a file, we need to notify the four types respectively. For each type of return record, we need to compare the name with the file we intend to hide. If we want to hide the first record, we can move the following structure forward and the length of the first record is the length of the first record, which will cause the first record to be rewritten. If we want to hide any other one, we only need to easily change the value of nextentryoffset in the previous record. If we want to hide the last record, change its nextentryoffset to 0. Otherwise, the value of nextentryoffset should be the sum of the value of the record we want to hide and the value of the previous nextentryoffset. Then modify the unknown change of the previous record.
It is the index of the next search. Change the value of the unknown variable in the previous record to the value of the unkown variable in the record to be hidden.
If no records should be visible are found, status_no_such_file is returned.
# Define status_no_such_file 0xc000000f
The same as the Hidden Port. For more information, see "disappear" in the NT operating system.
5. Let's talk about the ring3 rootkit idea proposed by yuanfan on xcon. Synchronous and asynchronous port multiplexing is achieved by attaching local APIs. Traces are hidden by means of auto-deletion and resurrection, which are not detected.

**********************************
Solutions to some hidden Technologies

As mentioned above, there is a way to break through the process object deletion from the process two-way linked list. Actually, smart people have already thought of it. The linked list required by NtQuerySystemInformation has been manipulated. However, windows dispatcher schedcher is different from the linked list. In this case, we can read another linked list used by windows dispatcherscheduler to list processes. That is to say, you can directly list processes by reading KiWaitInListHead and KiWaitOutListHead, which breaks through the method of modifying the hidden process of the two-way linked list. Pjf provides code by reading KiWaitInListHead to list hidden processes.
However, this detection method was soon broken through, namely replacing the process linked list of the kernel.
Another person suggested using the HOOKSwapContext method for detection. As long as the thread is scheduled by the processor, it cannot be escaped.
Some people do not know much about this function. Let me talk about this function.
In WINDOWS 2 K/NT/XP, the scheduling object of the processor is a thread. In a non-smp OS, there may be only one process processed by the CPU in a certain period of time. Each process allocates a specific CPU time slice for execution, and the CPU clock interruption of the system determines the time slice allocated by each process. That is, the process scheduling request generated when the system CPU clock is interrupted. When the processor clock is interrupted, KiDispatchInterrupt () is called to compare the time slice allocated by the current process. If it is used up, KiQuantumEnd () is called () select a new thread (ETHREAD) based on the thread priority and other information with a specific scheduling algorithm, and then return the value
The ETHREAD structure is used as a parameter to call SwapContext () to set parameters in ETHREAD and EPROCESS, replace the corresponding structure in KPCR to complete thread switching, and schedule it to the thread (ETHREAD) of another process (EPROCESS) continue. It can be said that the thread switching of the CPU is inseparable from the SwapContext function. Of course, all the threads executed by the rootkit are switched through the SwapContext function to make it processed by the CPU.
After that, someone proposed to replace the thread scheduling to avoid this kind of detection.
In my opinion, this detection method will occupy a lot of resources. After all, CPU thread switching is very frequent. If anyone has the conditions, check the number of thread switches in one second.
In Part 6, I will talk about rootkit detection.
*************************

Aboutring0 Rootkit
There is a spear, a shield, and a Trojan, and anti-virus software. However, in this endless tug-of-war between the two sides, Trojans are always at a disadvantage. In particular, anti-virus software has been used to kill Trojans, it is truly the point of "No need. What makes anti-virus software a long-term advantage? There is only one reason: Anti-Virus Software/firewall is dominant, with ring0 as the dominant factor, and ring3 as the supplementary factor. The war on trojans and anti-virus software/firewall is an asymmetric war, just like the war on the base and the United States. From a naked network software remote control software, Trojans have evolved to rebound Trojans, DLL-type Trojan horses, and now the "stealth" Trojan horses have become increasingly thick. However, a new trojan was just born and soon it was blacklisted by anti-virus software to collect signatures and be attacked everywhere. Today's "good Trojan"
It must have features such as no process, no port, and difficult to detect and kill. However, in the traditional ring3, it is believed that the trojan technology has little room for development and must go to ring0, so that anti-virus software/firewall can be used on an equal footing. Stepping into ring0 is a new direction for Trojan Horse development.
What are the advantages of ring0 compared with traditional Trojans? Let's take a look:
1. No process.
After the ring0 Trojan is compiled, it is a sys file. Like the DLL file, it is inserted into the process for running. However, DLL inserts the address in the user zone under 0x80000000, while ring0 Trojans are inserted in the system zone where the address is above 0x80000000, and all processes are shared, as long as it does not provide the unload routine, it is almost impossible to detach a system, and there are not many tools to list the mounted sys modules in the system.
2. No port.
The ring0 Trojan can directly control the network card to send and receive packets, and the system and firewall do not know at all. Therefore, it can use any port or protocol. Or break through the firewall blocking by making the firewall's NDIS driver invalid.
3. Hard to find, difficult to find and kill, and strong viability. Functions exported from the following three system modules: kernel, hal. dll, and ndis. sys. In addition, the Administrator and the above permissions are required to install the RING0 Trojan. If you only get the GUEST permission of the BOT, you must try to improve the permissions. The above description of the RING0 Trojan is just an idea. I have never implemented it using code, and I don't know if anyone has written such a trojan. I hope someone will correct me. But for programmers, this is a big challenge. It can be written to prove your ability!

**************************

Rootkit Detection
Like viruses, rootkit is "followed" by antivirus software vendors. As described in the above about ring0 rootkit, it is an endless tug-of-war. Many people who love technology also like to challenge them, so the detection technology of rootkit is also increasing. For example, EPA (executes path analysis ). Rootkit can be hidden by modifying system calls (as mentioned in the third part of this Article .), It will certainly be different from the normal system. When the system call path changes, we can detect the existence of rootkit through comparative analysis. Of course, this is also flawed. Check every time a system call occurs, as shown in the preceding figure
HOOK SwapContext is the same. Will consume a lot of system resources. Second, implementation is difficult.
There is also an anti-virus method, just like dealing with viruses. However, this method is passive. Besides, many rootkits are not exposed, so they are not very effective.
Another new detection method is Differentialtesting ). However, it is easy to break through. It is estimated that the subsequent rootkit can be used .......
Check and test some rootkit. You can use pjf's icesword. It is a very good detection tool. The ice enumeration process uses more than one method. Do not think that he can find everything. PS: However, do not call SoftICE during use; otherwise, it will crash because of the anti-debugging mechanism of ice. You can also try the knlsc of zzzevazzz. However, it will be very difficult to completely clear it after detection, which may cause system faults. Early defense is still important. Here are some methods to prevent rootkit. As for the defense of rootkit, it is also essential for anti-virus software. some well-known rootkits will also be scanned and killed. Some settings can prevent rootkit implantation, for example, prohibit access to \ device \ physicalmemory.
. Disable system calls for driver loading. However, if the setting is too strict, the problem may occur. Remember that I set it randomly, resulting in bsod when rootkit is implanted .....

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.