Samhain | ||
---|---|---|
<<< Previous | Configuration — samhain, the file monitor | Next >>> |
This option is currently supported only for Linux, kernel versions 2.2.x and 2.4.x, on ix86 machines, and for FreeBSD (tested on FreeBSD 4.6.2).
![]() | Warning |
---|---|
It is incorrect to assume that disabling support for loadable kernel modules protects against runtime kernel modifications. It is possible to modify the kernel via /dev/kmem as well. |
A rootkit is a set of programs installed to "keep a backdoor open" after an intruder has obtained root access to a system. Usually such rootkits are very easy to install, and provide facilities to hide the intrusion (e.g. erase all traces from audit logs, install a modified 'ps' that will not list certain programs, etc.).
While "normal" rootkits can be detected with checksums on programs, like samhain does (the modified 'ps' would have a different checksum than the original one), this method can be subverted by rootkits that modify the kernel at runtime, either with a loadable kernel module (LKM), i.e. a module that is loaded into the kernel at runtime, or by writing to /dev/kmem (this allows to 'patch' a kernel on-the-fly even if the kernel has no LKM support).
Kernel rootkits can modify the action of kernel syscalls. From a users viewpoint, these syscalls are the lowest level of system functions, and provide access to filesystems, network connections, and other goodies. By modifying kernel syscalls, kernel rootkits can hide files, directories, processes, or network connections without modifying any system binaries. Obviously, checksums are useless in this situation.
When a system call (e.g. open() to open a file) is made by an application, the flow of control looks like this:
An interrupt is triggered, and execution continues at the interrupt handler defined for that interrupt. On Linux, interrupt 80 is used.
A rootkit could replace the kernels interrupt handler by an own function.
Samhain checks the Interrupt Descriptor Table for modifications.
The interrupt handler (named system_call() on Linux) looks up the address of the requested syscall in the syscall table, and executes a jump to the respective address.
A rootkit may (a) modify the interrupt handler to use a (rootkit-supplied) different syscall table, or (b) modify the entries in the syscall table to point to the rootkits replacement functions.
Samhain checks (a) the interrupt handler, and (b) the syscall table for modifications.
The syscall function is executed, and control returns to the application.
A rootkit may overwrite the syscall function to place a jump to its own replacement function at the start of the syscall function.
Samhain checks the first few bytes of each syscall function for modifications.
On FreeBSD, currently only the syscall table (2b) and the system call (3) are checked.
![]() | NOTE |
---|---|
If you use the option ./configure --enable-khide to use a kernel module to hide the presence of samhain, the first detected modification of the sys_getdents syscall will only cause a warning (rather then an error), as it is presumed to be caused by the samhain_hide LKM). |
To use this facility, you need to compile with the option:
./configure --with-kcheck=/path/to/System.map (Linux), or
./configure --with-kcheck (FreeBSD).
On Linux, System.map is a file (sometimes with the kernel version appended to its name) that is generated when the kernel is compiled, and is usually installed in the same directory as your kernel (e.g. /boot), or in the root directory. To find it, you can use: locate System.map
This facility is configured in the Kernel section of the configuration file.
[Kernel] # activate (0 for switching off) KernelCheckActive=1 # interval between checks (in seconds, default 300) KernelCheckInterval=20 # this is the severity (see section the Section called Severity levels in the chapter called Configuration — Basic) SeverityKernel=crit |
Error messages start with 'POLICY KERNEL'. There are three types of them: (a) modified interrupts: old and new address, segment, privilege level, and type are listed, (b) modified syscall table/interrupt handler: old and new address are listed, and (c) modified syscall code: old and new code are listed.
If an empty slot in the interrupt descriptor table (old address zero) has been modified, this indicates that a new interrupt has been installed. This cannot modify the behaviour of user applications (which would not use that interrupt), but could be used by a dedicated (rootkit-supplied) application to perform some action (e.g. elevate privileges).
Likewise, if an empty slot in the syscall table (syscall name sys_ni_syscall/_nosys) has been modified, this cannot modify the behaviour of user applications, but again could be used by a dedicated (rootkit-supplied) application to perform some action.
<<< Previous | Home | Next >>> |
Checking the file system for SUID/SGID binaries | Up | Monitoring login/logout events |