Linux Kernel Auditor v0.2.1 GPL 2006 This package contains two modules. You can build them with 'make'. You will need kernel source or a kernel-devel package installed. 1. module_hunter.c - Checks for hidden modules This module will search though the vmalloc memory region for structures that look like 'struct module' entries. It will print any 'struct module' entries that it finds that ARE NOT LISTED in the system module list. This module is not failsafe. Just because it reports nothing is present does not mean you are clean. 2. scprint.c - Prints out the syscall table This module can verify the syscall table using a few different means. A. IDT Lookup The module can look up the syscall_call function call in position 0x80 of the interrupt table and finds the sys_call_table call inside this function. This method covers the two major ways syscalls can be subverted. This method creates the file /proc/idt_syscall. When you cat this file, the module traverses the IDT and reads the syscall table to 'dmesg'. The module parameter system_call=
can be used to manually specify the system_call symbol instead of traversing the IDT. B. Sysenter Lookup For systems that use the sysenter instruction, the same basic technique can be done using the sysenter MSR and following the sysenter_entry function. This method creates the file /proc/sysenter_syscall. Catting this file traverses the sysenter MSR and reads the syscall table to 'dmesg'. The module parameter se_entry=
can be used to manually specify the sysenter_entry symbol instead of reading it from the MSR. C. User Specified Address You can specify the sys_call_table parameter table=0. This is not very robust, because a rootkit can hijack the IDT or the code it calls. This method uses the module paramter table=
to read the sys_call_table directly when you cat /proc/user_syscall. A file has been provided for you that creates 3 diffs: kern-map.diff - The differences between the kernel and kern-syms.diff - The differences between the kernel and /proc/kallsyms map-syms.diff - The differences between kallsyms and (should be 0) It is normal that there are some minor differences between the kernel and the symbol files. The crucial symbols that SHOULD NOT differ are: sys_read sys_write sys_open sys_getdents sys_socketcall sys_query_module sys_setuid sys_execve sys_chdir sys_fork sys_ioctl sys_kill system_call sysenter_entry To help detect the technique discussed in Each of these files will also accept input in the form of a syscall followed by a length. Ie: echo "sys_read 100" > /proc/idt_syscall This will cause a char array sys_read to be printed to dmesg that contains the bytecode of the system call sys_read. You can then cut and paste this to the bottom of the analyze_this.c file and run 'make'. Once the file is built, you can run the following: $ gdb ./analyze_this (gdb) disass sys_read You can then run $ gdb /path/to/kernel/vmlinux (gdb) disass sys_read And compare the two outputs. The most important thing to watch for is that the first 2-3 lines are push, sub and mov instructions and not a jmp or a call instruction to some random address. Note that the addresses for calls and such will be off, since they are relative, but the rest of the structure should be the same. NOTE: People running stock kernels may not have a vmlinux file. For rpm based systems, you will have to download the kernel source rpm and run # rpmbuild --target i686 -bc kernel-.src.rpm This will create a vmlinux file in /usr/src/redhat/BUILD/kernel-/linux-/vmlinux Good luck and happy hunting! P.S. This does not cover all your bases. Future versions of this auditor will need to address hooking the keyboard interrupt directly and hooking the page fault handler.