Hack #124. Scan for Rootkits

Use chkrootkit to determine the extent of a compromise.

If you suspect that you have a compromised system, it is a good idea to check for a rootkit, which is a collection of programs that intruders often install after they have compromised the root account of a system. These programs help the intruders clean up their tracks and provide access back into the system.

Rootkits sometimes leave processes running to allow the intruder to return easily and without the system administrator’s knowledge. This means that the rootkit needs to modify some of the system’s binaries (such as ps, ls, and netstat) in order to not give away the backdoor processes that the intruder has put in place. Unfortunately, there are so many different rootkits that it would be far too time-consuming to learn the intricacies of each one and look for them manually. Thankfully, scripts like chkrootkit (http://www.chkrootkit.org) will do the job for you automatically.

The main chkrootkit script calls various C programs to perform all of the tests it carries out. In addition to detecting over 50 different rootkits, chkrootkit detects network interfaces that are in promiscuous mode, altered lastlog files, and altered wtmp files. These files contain times and dates when users have logged on and off the system, so if they have been altered, this is evidence of an intruder. chkrootkit also performs tests to detect kernel-module-based rootkits.

It isn’t a good idea to install chkrootkit on your system and simply run it periodically, since an attacker might simply find the installation and change it so that it doesn’t detect his presence. A better idea is to compile it and put it on removable or read-only media. To compile chkrootkit, download the source package and extract it. Then, go into the directory that it created and run the make sense command.

Running chkrootkit is as simple as typing ./chkrootkit from the directory in which it was built. When you do this, it will print each test that it performs and the result of the test:

# ./chkrootkit
ROOTDIR is \Q/'
Checking \Qamd'... not found
Checking \Qbasename'... not infected
Checking \Qbiff'... not found
Checking \Qchfn'... not infected
Checking \Qchsh'... not infected
Checking \Qcron'... not infected
Checking \Qdate'... not infected
Checking \Qdu'... not infected
Checking \Qdirname'... not infected
Checking \Qecho'... not infected
Checking \Qegrep'... not infected
Checking \Qenv'... not infected
Checking \Qfind'... not infected
Checking \Qfingerd'... not found
Checking \Qgpm'... not infected
Checking \Qgrep'... not infected
Checking \Qhdparm'... not infected
Checking \Qsu'... not infected
...

That’s not very interesting, because the machine hasn’t been infected (yet). In contrast, here’s some output from a machine that has been infected by a simple rootkit that replaces system binaries with versions that have been modified to hide the intruder’s presence:

ROOTDIR is \Q/'
Checking \Qamd'... not found
Checking \Qbasename'... not infected
Checking \Qbiff'... not found
Checking \Qchfn'... not infected
Checking \Qchsh'... not infected
Checking \Qcron'... not infected
Checking \Qdate'... not infected
Checking \Qdu'... not infected
Checking \Qdirname'... not infected
Checking \Qecho'... not infected
Checking \Qegrep'... not infected
Checking \Qenv'... not infected
Checking \Qfind'... not infected
Checking \Qfingerd'... not found
Checking \Qgpm'... not infected
Checking \Qgrep'... not infected
Checking \Qhdparm'... not infected
Checking \Qsu'... not infected
Checking \Qifconfig'... INFECTED
Checking \Qinetd'... not tested
Checking \Qinetdconf'... not found
Checking \Qidentd'... not found
Checking \Qinit'... not infected
...

As you can see, the ifconfig command has been replaced. This is because it’s possible for a system administrator to easily see if a sniffer is active by running the ifconfig command and checking to see if it shows the network interface in promiscuous mode.

More sophisticated rootkits insert code into the kernel to subvert key system calls in order to hide an intruder’s activities. If you see something similar to the following, it means a rootkit that uses loadable kernel modules (LKMs) to do this has been installed on the system:

Checking \Qlkm'... You have     1 process hidden for readdir command
You have     1 process hidden for ps command
chkproc: Warning: Possible LKM Trojan installed

chkrootkit can also be run on disks mounted in another machine; just specify the mount point for the partition with the -r option, like this:

# ./chkrootkit -r /mnt/hda2_image
         

Also, since chkrootkit depends on several system binaries, you might want to verify them before running the script (using the Tripwire [Hack #122] or RPM [Hack #123] methods). These binaries are awk, cut, egrep, find, head, id, ls, netstat, ps, strings, sed, and uname. If you have known good backup copies of these binaries, you can specify the path to them instead by using the -p option. For instance, if you copied them to a CD-ROM and then mounted it under /mnt/cdrom, use a command like this:

# ./chkrootkit -p /mnt/cdrom
         

You can also add multiple paths by separating each one with a colon (:).

Alternatively, instead of maintaining a separate copy of each of these binaries, you can simply keep a statically compiled copy of BusyBox (http://www.busybox.net) handy. Intended for embedded systems, BusyBox can perform the functions of over 200 common binaries, and it does so using a very tiny binary with symlinks. A floppy, CD, or USB keychain (with the read-only switch enabled) with chkrootkit and a static BusyBox installed can be a quick and handy tool for checking the integrity of your system.