that is where our rootkit detection problems start.
How can we detect rootkits? There are simple and complex pseudo-solutions. I say “pseudo” because of the number of false positives we may get. I believe
the probability of detecting a new rootkit in our system is directly proportional to our knowledge of the subject. Or, in other words, we should know about how rootkits behave.
As I will show later, there are utilities you can use to detect rootkits. These utilities, which are good enough, sometimes give false positives. They can also give false negatives, which in this case is terrible. This is the reason to do behavioural analyses of rootkits. The only way to detect something is to learn about it. It is sometimes a bit of a sixth sense. I know people who can sit down, use the shell a bit, and suddenly they say “I’m pretty sure you’ve been hacked”.
Of course, you also need to know your system. But, well, that is something that only experience gives. In the meantime, I really hope I can help you a bit with this article.
As I stated before, a rootkit is usually a set of:
1) Trojanized system utilities and daemons
2) Additional programs
3) Kernel Modules (now quite common)
Let’s look at each individually.
(1) Trojanized System Utilities and Daemons
Some examples and explanations:
ls: usually enables the attacker to hide files and directories. It uses a special configuration file.
du: again, hides certain directories and does not count them against disk usage. It also uses a configuration file.
df: You guessed it! It gives more free space than you actually have, to conceal the fact that a large part of the disk is being used to store sniffer logs.
login: Gives automatic root access, usually after a special trigger is activated. What is special about this root access through login is that loggin can be disabled. It also allows direct login to users other than root.
netstat: Hides connections, based upon system variables such as socket pathname, uid, etc.
chfn/chsh/passwd: Usually has a hidden uid 0 shell.
inetd/xinetd: Usually binds an interactive shell to certain port. Most of them can make use of access control features.
ifconfig: If a sniffer is running, it hides the fact that a network interface is probably in promiscuous mode.
ps/top: Filters out processes from the listing, based on paremeters read from a configuration file. Actually, if the proc pseudo filesystem were unmounted, and a trojanized proc-like filesystem module is loaded and then mounted, one could control a wide range of system utilities that read required information from /proc.
syslogd: It will not write messages which contain configured substrings or regular expressions.
md5sum: It returns a certain md5 hash for certain file. Completely configurable. Scripts that use this binary to verify filesystem integrity can be easily compromised this way.
rshd: (Not used very much anymore) Gives the ability to bind an interactive root shell.
At this point you probably get the idea. As you can see, the pattern that rootkit programmers follow for Trojanized Utilities looks like this:
a) Divide utilities into groups, or think about categories and then find which utilities fit them.
b) Add trojan code based upon the category. This means that a utility that sits in the “Login and/or Remote Access” category will probably have trojan code to enable passwordless root login, for example. The same way, another utility in the “Kernel-Related” category, like lsmod, will not show certain kernel modules in the loaded kernel modules list lsmod provides by reading /proc/modules.
Of course, this process can be applied to any installed program or utility.
As you can probably imagine, utilities that are used locally (i.e, when the user is logged onto the system, either via network or at the console) at the shell to show certain vital or important information (e.g, ps) are potential victims. These kinds of utilities are frequently used by users and, especially, sysadmins.
(2) Additional Programs
These are additional programs used by the attacker when he is logged onto the compromised system. Among these utilities we can, and probably will, find sniffers, zappers, encryption utilities, rootkit post-installation configuration programs, file transmission utilities using a special protocol (like ICMP encapsulation) and the like.
It is easy to figure out that these files need to be kept on the compromised system for them to be worth using. The same applies for files generated by programs like sniffers: sniffer logs do take a lot of disk space if not properly tuned.
Usually, the directory where files will reside is going to be well protected. For example, the rootkit can be configured only to allow certain UIDs to get into certain directories. In other circumstances it will hide the directories.
This is achieved by: (1) Using trojanized ls/cd/etc commands or by using a Linux Kernel Module (3). The second approach was some kind of a revolution. Fewer infected files means a lower probability of detection. And since using a kernel module gives a lot of power, a lot of additional features can be conceived.
Usually, rootkit sniffers are developed with the “go to the background and make no noise” approach. This means that they sniff traffic, especially passwords, but they hide the fact that they are running, usually by changing the name that appears on a ps. Trojanized ps/top utilities or /proc filesystems are good approaches to hide processes based on certain configuration parameteres.
Then you have wtmp/utmp/lastlog zappers. As you probably know, these are the files read by the w and last utilities. Early rootkit zappers used to zero the records you told them to (i.e which user to zero-overwrite). Current ones just physically remove the record, instead of logically overwriting it with zeroes. Some crackers forget that these are not the only places where their tracks can appear.
Of course, there are a whole bunch of additional utilities, like encryption/decryption utilities, but now there are steganography techniques that are starting to be used. Steganography hides files inside other files, by actually replacing the lower bits of an image or MP3 file, for example. One cannot usually see (in the case of an image) or hear (mp3 file) the difference between the real and the ‘injected’ version of the file. Of course, the original file size grows, sometimes quite noticeably.
File transmission utilities that help the attacker get files out of the system via methods that do not make system noise (i.e log files being written) are not that common, but are still pretty interesting. I remember when I coded a proof of concept utility that would allow me to send files over a ping packet. From a traffic point of view, I was just pinging some remote system. From my point of view, I was transmitting a file. In a very slow, but largely undetectable, way.
(3) Kernel Modules
The main difference between a normal rootkit and an LKM Rootkit is very simple: normal rootkits replace system utilities that enable the attacker to hide files, processes and network connections.
An LKM Rootkit, on the other hand, does something a bit more interesting: it replaces the location of system calls, changing the original memory addresses to something else, and in that different location there is a trojanized version of the system call. So, they do not need to modify utilities (or libraries), they simply replace what these utilities and
libraries use! Rootkits of this sort go by the names of Rkit and Adore LKM, just to mention a couple of the most common ones.
Here is a list of the typically modified system calls: sys_clone, sys_close, sys_execve, sys_fork, sys_ioctl, sys_kill, sys_mkdir, sys_read, sys_readdir, sys_write.