Article Title: Detailed description of advanced Hiding Technology in Linux. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
This article provides an in-depth analysis of the advanced Hiding Technology of files, processes, and modules in a Linux environment, including: Linux detachable module programming technology, modification of memory image, and direct modification of system calls, technology for hiding specific processes through the Virtual File System proc.
Hiding technology is widely used in computer system security, especially in network attacks. When attackers successfully intrude into a system, it is particularly important to effectively hide attackers files, processes, and loaded modules. This article will discuss the advanced Hiding Technology of files, processes and modules in Linux systems. Some of these technologies have been widely used in various backdoor or security detection programs, and some of them are just getting started, it is still in the discussion stage, with few applications.
1. Hiding Technology
1.1.Linux interrupt control and system call
Intel x86 series microcomputer supports 256 types of interrupts. To make it easier for the processor to identify each interrupt source ~ 256 number, that is, assign an interrupt type code n. Intel calls it an interrupt vector.
Linux uses an interrupt vector (128 or 0x80) to call the system. All system calls use the unique entry system_call to enter the kernel, when a user's dynamic process executes an int 0x80 Assembly command, the CPU switches to the kernel state and starts to execute the system_call function, the system_call function then obtains the address of the system call through the system call table sys_call_table for execution. The system call table sys_call_table stores the addresses of all system call functions. Each address can be indexed by the system call number. For example, sys_call_table [NR_fork] indexes the address that the system calls sys_fork.
Linux uses an Interrupt Descriptor (8 bytes) to indicate information about each interrupt. The format is as follows:
Offset 31 .... 16. Some logos, type codes, and reserved bits
Segment selection offset 15 .... 0
All interrupt descriptors are stored in a continuous address space. This continuous address space is called the Interrupt Descriptor Table (IDT), and its starting address is stored in the Interrupt Descriptor Table register (IDTR, the format is as follows:
32-bit base address value limit
The corresponding links of each structure can be expressed as follows:
Through the above instructions, we can find the system_call function address through the IDTR register: Find the Interrupt Descriptor Table Based on the IDTR register, And the 0x80 In the Interrupt Descriptor Table is the address of the system_call function, this address will be applied in later discussions.
1.2.Linux LKM (capable of loading kernel modules) Technology
Linux provides a module mechanism to keep the kernel small in size and facilitate function expansion. Modules are part of the kernel, but they are not compiled into the kernel. They are compiled into the target file and dynamically inserted or removed from the kernel as needed during running. Because the module runs as a part of the Linux kernel after being inserted, module programming is actually kernel programming. Therefore, some resources exported from the kernel can be used in the module, for example, the address of the system call table (sys_call_table) exported by the kernel earlier than Linux2.4.18 can be directly modified based on the address to change the system call. Initialization and cleanup functions must exist in module programming. Generally, the two functions are init_module () and clearup_module () by default, starting from kernel version 2.3.13, you can also rename these two functions. The initialization function is called when the module is inserted into the system. In this function, you can register some functions and symbols, the clearing function is called when the Module removes the system. Some restoration work is usually done in this function.
1.3.memory image in Linux
/Dev/kmem is a character device and an image of the master computer. It can be used to test or modify the system, when the kernel does not export the sys_call_table address or the module cannot be inserted, you can use this image to modify the system call to hide files, processes, or modules.
1.4.proc File System
The proc file system is a virtual file system that is implemented through the interface of the file system and used to output the running status of the system. It provides an interface for communication between the operating system and application processes in the form of a file system, this allows applications to securely and conveniently obtain information about the current operating status of the system, kernel, and modify the configuration information of some systems. Because proc is implemented using the interface of the file system, it can be accessed just like a common file, but it only exists in the memory.
2. Technical Analysis
2.1 hide files
In Linux, sys_getdents is the system call used to query file information. This can be observed through strace. For example, strace ls will list the system calls used by the ls command, from this, we can find that ls performs operations through sys_getedents. When querying information about a file or directory, the Linux system uses sys_getedents to perform corresponding query operations, and passes the obtained information to the program running in the user space, therefore, if you modify the system call and remove the information related to some specific files in the result, all programs that use the system call will not be able to see the file, thus achieving the purpose of hiding. First, we will introduce the original system call. Its prototype is:
Int sys_getdents (unsigned int fd, struct dirent * dirp, unsigned int count)
Fd is the file descriptor pointing to the directory file. This function reads the corresponding dirent structure based on the directory file pointed to by fd and puts it into dirp. count indicates the data volume returned by dirp, if this function is correct, the return value is the number of bytes filled with dirp. Is the modified system call hacked_getdents execution process.
The hacked_getdents function actually calls the original system call and removes the file information related to the specific file name from the obtained dirent structure, in this way, the application will not be able to see the existence of the file after it is returned from the system call.
It should be noted that in some newer versions, file information is queried through sys_getdents64, but its implementation principle is basically the same as that of sys_getdents, therefore, in these versions, you can use methods similar to the above to modify system calls and hide files.
2.2 hidden modules
The above analysis shows how to modify system calls to hide files with specific names. In actual processing, modules are often used to modify system calls. However, when a module is inserted, if no hidden measure is taken, it is easy for the other party to discover. Once the other party discovers and uninstalls the inserted module, all files hidden by this module will be exposed, therefore, we should continue to analyze how to hide modules with specific names. In Linux, the system call used to query module information is sys_query_module, so you can hide a specific module by modifying the system call. First, explain the original system call. The original system call prototype is:
Int sys_query_module (const char * name, int which, void * buf, size_t bufsize, size_t * ret)
If the parameter name is not empty, access the specific module. Otherwise, access to the kernel module. The which parameter indicates the query type. When which = QM_MODULES, return the names of all currently inserted modules, the number of blocks stored in the buff and in the ret. The buffsize is the size of the buf buffer. In the module hiding process, you only need to process the which = QM_MODULES. The modified system call process is as follows:
1) Call the original system call. If an error occurs, the error code is returned;
2) If which is not equal to QM_MODULES, it does not need to be processed and is returned directly.
3) process from the beginning of the buf. If a specific name exists, the name of the subsequent module is overwritten.
4) Repeat (3) until all the names are processed, the returned result is correct.
2.3 hide a process
In Linux, there is no system call to directly Query Process Information. commands like ps to query process information are implemented by querying the proc file system, the proc file system has been introduced in the background knowledge. Because it applies the interface Implementation of the file system, you can also use the File hiding method to hide files in the proc file system, you only need to add the proc file system judgment in hacked_getdents. Because proc is a special file system that only exists in the memory and does not exist on any actual device, therefore, the Linux kernel assigns a specific primary device number 0 and a specific secondary device Number 1. In addition, because there is no corresponding I node in the external storage, therefore, the system also assigns it a special node number PROC_ROOT_INO (with a value of 1), while the No. 1 index node on the device does not need to be retained. Through the above analysis, we can find out whether a file belongs to the proc file system:
1) obtain the inode structure dinode corresponding to the file;
2) if (dinode-> I _ino = PROC_ROOT_INO &&! MAJOR (dinode-> I _dev) & MINOR (dinode-> I _ dev) = 1) {This file belongs to the proc file system}
Through the above analysis, the pseudocode representation of hiding a specific process is provided:
Hacket_getdents (unsigned int fd, struct dirent * dirp, unsigned int count)
{
Call the original system call;
Get the node corresponding to fd;
If (this file belongs to the proc file system & this file name needs to be hidden)
{Remove information about this file from dirp}
}
[1] [2] Next page