Passerby A · 2015/01/23 9:52
0 x00 introduction
A Linux server is found to be abnormal as shown in the following figure, and it is confirmed to be implanted with Rootkit, but the routine Rootkit detection method used by operation and maintenance personnel is invalid. What else can we do in this case?
Figure 1 Linux server with Rootkit embedded
All dark link HTML files ls are not visible.
With ls-al absolute path, it can be seen but cannot be deleted.
The unique Uids and Gids of these dark chains are 2511744398:4043361279.
Executing chown 2511744398:4043361279 on any file will behave the same as a dark chain file.
After the disk NFS is mounted to a normal system, no change occurs.
0x01 Rootkit Implementation and Detection Method
Generally speaking, the Rootkit can be detected in the following ways:
1. Trusted shells -- use statically compiled binaries: lsof, stat, strace, last... Detection tools and scripts: rkHunter, chkRootKit, OSSEC 3. LiveCD -- DEFT, Second Look, Helix 4. Dynamic analysis and debugging: using GDB to analyze System. Map and vmlinuz image /proc/kcore 5. Direct debugging of raw devices: debugFSCopy the code
Before analyzing the pros and cons of these detection methods, let’s take a look at the general implementation principle of Linux Rootkit through Figure 2
Figure 2 The general flow of system command execution in Linux
System commands/applications working at the Ring3 layer (user space) call the system.so file note 1 when they implement some basic function. The basic functions of these. So files, such as file reading and writing, are read from the Syscall Table of Ring0 layer (kernel space), and the corresponding Syscall(system call Table) is applied to the hardware, and the file reading and writing is finally completed.
So what happens to this process if you get Rootkit? See figure 3 for an idea.
Figure 3 General execution flow of Rootkit
Rootkit tampered with the memory address of Syscall in the Syscall Table, causing the program to read the modified Syscall address and execute malicious functions to achieve its special functions and purposes.
The figure above just lists a typical Rootkit workflow. Different types of Rootkits can be generated by modifying the program to read different parts of Syscall. Let’s briefly list them.
Rootkit part implementation:
1. Intercept interrupt-redirect sys_call_table and modify IDT 2. Hijack system call - modify sys_call_table 3. Inline hook- modify sys_call, insert JMP directiveCopy the code
This part is not the focus of this article and will not be repeated. Knowing the implementation principle of Rootkit, let’s go back and compare the advantages and disadvantages of the conventional Rootkit detection method.
For detection using statically compiled binaries, if the Rootkit modifs Syscall, the output is also unreliable and we cannot see anything hidden by the Rootkit.
So if the Rootkit detection tool is used, let’s briefly analyze the detection principle of RkHunter.
In the rkHunter script file, the scanRootKit function code is as follows:
Figure 4 scanRootKit function in RkHunter
Note: The following two variables are defined in its installation script
#! bash RKHTMPVAR="${RKHINST_SIG_DIR}" RKHINST_SIG_DIR="${RKHINST_DB_DIR}/signatures"Copy the code
Figure 5 List of files in Signatures directory — Rootkit signature list
From the above code we can see that rkHunter scans the Rootkit and calls three important variables: SCAN_FILES, SCAN_DIRS, and SCAN_KSYMS, which are used for checking each Rootkit.
The following four pictures are the specific codes detected by Adore and KBeast Rootkit respectively.
Figure 6 Detection process of classic Rootkit Adore in RkHunter
Figure 7 a listing of files and directories that detect Adore in RkHunter
Figure 8 Rootkit KBeast detection process in RkHunter
Figure 9 shows a listing of files and directories to detect KBeast in RkHunter
Based on the above analysis, we can see that RkHunter only checks whether there are corresponding files in the default installation path of the known Rootkit component and compares the signature of the files. This method of detection is obviously too crude to be effective against modified/new rootkits.
And another popular Rootkit detection tool chkRootKit, its LKM Rootkit detection module source file is chkproc.c, last updated on January 11, 2006. Detection is similar to rkHunter, also based on signature detection and comparing the output of the ps command to the /proc directory. Q2’s answer in its FAQ also confirms our conclusion.
Figure 10 Q2 of FAQ of CHkRootKit
After analyzing the implementation principles of common Rootkit detection tools, let’s take a look at the limitations of using LiveCD detection.
Using a LiveCD means using a clean cd-rom operating system to mount the original storage to do static analysis/reverse analysis of suspicious files in order to understand the Rootkit execution logic, what so/ KO files are dependent on, and what configuration files are being loaded. Therefore, if you do not find some Rootkit related files in advance, it is undoubtedly a cumbersome process to directly check the entire file system. Moreover, this approach can only be used if emergency responders have physical access to the server, which is inconvenient for a hosted environment in a machine room. In fact, the use of a LiveCD is more common in Rootkit purging or forensic forensics than it is in the lead-up.
Based on the above analysis, we briefly summarize the effect of Rootkit detection, as shown in the following table.
Rootkit Comparison of detection methods
Testing way | Limitations/Defects |
---|---|
Use statically compiled binaries | Works in user space and has no effect on Ring0 layer Rootkit. |
Tools rkhunter, chkrootkit | Scanning known Rootkit features, comparing file fingerprints, and checking /proc/modules have very limited effect. |
LiveCD:DEFT | Rootkit Active processes and network connections cannot be seen and can only be statically analyzed. |
GDB dynamic analysis debugging | Debug analysis /proc/kcore, the threshold is slightly higher and more complex. Not suitable for emergency response. |
DebugFS Direct read and write to raw devices | Independent of kernel modules, complex, only suitable for laboratory analysis. |
Given the drawbacks of conventional Rootkit detection, is there a better way to do it?
Now we introduce the Rootkit detection method based on memory analysis in detail.
0x02 Memory based detection and analysis Rootkit
Rootkits are difficult to detect, mainly because of their high hiding characteristics, which are generally hidden in processes, ports, kernel modules and files. However, no matter how hidden it is, there must be a hint of these aspects in memory if we can dump physical memory normally with debug symbols. With kernel’s data structure to parse the memory files, it can have a real “description” of the system’s activity state at that time, and then compare it with the “false” results directly output by executing commands in the system to find out suspicious aspects. Here are some of the principles.
1. Detection process based on memory analysis
In Linux, the ps-aux command is generally executed to view the process. In essence, it reads /proc/pid/to obtain the process information. Task_struct note 3 of the kernel also contains the process PID, creation time, image path, etc. This means that information about each process can be obtained from its task_struct memory address. Furthermore, each task_struct is strung together with next_Task and prev_Task to form a bidirectional linked list that can be traversed through the process via the for_each_task macro. We can find the memory address of init_task symobol (ancestor process) with PID 0 and iterate through it to simulate the effect of PS. See below for some details.
Figure 11 task_struct in the kernel
In addition, the Linux kernel has something called the PID Hash Chain, as shown in Figure 12. It is an array of Pointers, each element pointing to an element in a task_struct list of PIds, that allows the kernel to quickly locate the corresponding process based on the PID. So the analysis pid_hash can also be used to detect hidden processes and get information about them more efficiently.
Figure 12 PID Hash Chain in the kernel
2. Process Memory Maps
In task_struct, MM_struct note 4 describes the entire virtual address space of a process, and the process mapping is mainly stored in a vm_area_struct structural variable MM_rb note 5 and mmap, as shown in the following figure
Figure 13 Structure of mm_struct(memory descriptor)
Each VM_areA_struct node records the attributes of the VIRTUAL memory area (VMA), such as vm_start (start address), VM_end (end address), vm_flags (access permission), and the corresponding vm_file (mapping file). Getting information from memory is equivalent to getting the contents of /proc//maps.
3. Detect network connections and open files based on memory analysis (LSof)
Lsof (List Open Files) in Linux reads information from the /proc/pid/ folder. This information is also available via task_struct.
Figure 14 details of task_struct in the kernel
The structure of task_struct contains files pointing to files_struct, which is used to represent the open file table of the current process. The structure has an FD_array (File Descriptor array), and each element in the array, fd (File Descriptor), represents a File opened by a process. The structure of each File Descriptor contains directory entries dentry, File operations F_OPS, etc. This is enough to find the files open by each process.
In addition, when the f_OP structure member of a file is socket_file_OPS or its dentry.d_op is sockfs_dentry_operations, it can be converted to the corresponding Inet_sock structure. Finally get the corresponding network information.
4. Detect bash_history based on memory analysis
During post-penetration testing, attackers often use the history -c command to clear the command history that was not saved into the. Bash_history file. In Rootkit, setting HISTSIZE = 0 or HISTFILE = /dev/null is also a common way to hide command history. For the latter, since the bash process’s history is also recorded in the corresponding MMAP (its corresponding macro is defined as HISTORY_USE_MMAP note 6), its history can also be restored from the corresponding MMAP data through the history_list() function.
Figure 15 Function diagram of history_do_write in histfile.c of bash 4.0 source code
5. Detect kernel modules based on memory analysis
Checking the Rootkit by traversing all struct modules on the Module list is an alternative to the lsmod command. This method does not work if the Rootkit removes its LKM from the Module list but still loads it into memory.
Figure 16 Kernel Module List
However, rootkits are difficult to hide in the /sys/module/ directory, so we can still check for hidden kernel modules by traversing the Sysfs file system.
6. Check the Process credentials based on memory analysis
Prior to the 2.6.29 kernel, Rootkit promoted privileges for user-mode processes by setting their effective user ID and effective group ID to 0 (root). In later versions, kernel introduced the ‘cred’ structure. To this end, Rootkit keeps up with The Times and responds to this improvement by setting the same ‘cred’ structure as a root permission process. So by examining the ‘CREd’ structure of all processes, you can better find the active Rootkit.
7. Process of detecting Rootkit based on memory analysis
Due to space limitation, this paper will not introduce more principles and details, but simply summarize the general process of this method.
1 Create a profile of the target Linux server. 2 Dump complete physical memory. 3 Use the profile to parse memory image files and output system informationCopy the code
Figure 17 Schematic diagram of Rootkit detection based on memory analysis
0x03 Summary and Practice
The method of detecting Rootkit based on memory analysis has a great advantage over the conventional detection method, but it is not a cure-all. If it is disturbed by advanced Rootkit such as Bootkit, the physical memory of Dump is incorrect or incomplete, the next step is the attic in the sky. Also make sure that the System.map required to make a Profile has not been tampered with or replaced directly with a file from a Linux distribution with the same kernel version.
There are not many tools available to detect rootkits through memory analysis, each with its own advantages and disadvantages. As an open source tool in the field of judicial evidence, Volatility is a leader in this field. I recommend all colleagues to use and contribute codes. Students who are interested in memory detection and analysis technology are welcome to discuss with me. EOF
0 x04 note
Note 1: The Shared object (SO) file in Linux is similar to the DYNAMIC Link Library (DLL) file in Windows. It is used to provide functions and resources. Note 2: Syscall tables can be obtained by viewing the /boot/ system. map file. Note 3: Process Descriptor: To manage processes, the kernel must have a clear picture of what each process is doing. It must know, for instance, the process's priority, whether it is running on a CPU or blocked on an event, what address space has been assigned to it, which files it is allowed to address, And so on. This is the role of the process Descriptor -- a task_struct type structure whose fields contain all the information related to a single process. Note 4: mm_struct specifies the memory used by the corresponding program, such as all segments, the starting and ending positions of each main segment, the total size of the resident memory used, etc., which is usually referred to as memory descriptors. Red black tree of mappings. Note 6: HISTORY_USE_MMAP definition see bash - 4.0 - the SRC/lib/readline histfile. C line 475. Specific can see http://sourcecodebrowser.com/bash/4.0/histfile_8c_source.html.Copy the code
0x05 References
http://www.rootkitanalytics.com/kernelland/linux-kernel-rootkit.php https://media.blackhat.com/bh-us-11/Case/BH_US_11_Case_Linux_Slides.pdf https://www.safaribooksonline.com/library/view/understanding-the-linux/0596005652/ch03s02.html http://www.wowotech.net/linux/19.html http://www.lenky.info/archives/2012/04/1424 http://code.google.com/p/volatility/