使用KSAT检测可加载内核模块
1.目的
本文包括LKM基础,如何检测LKM。
2.LKM
什么是LKM?LKM是可加载内核模块的缩写,就是那些包含动态可加载部分的文件。通常LKM用来加载设备驱动程序和其它的硬件驱动程序。在Linux、Solaris和BSD(Free、Net和open)等操作系统可以见到LKM。本文集中讨论Linux。
在Linux中有几个工具来处理LKM的诸如加载、列表和卸载等操作。在讨论这些工具之前,我们先看看一些重要的关于LKM的文件和目录。第一个目录是/lib/modules/"kernel_vision",让我们看看在这个目录下的内容:
block build cdrom fs ipv4 misc modules.dep modules.isapnpmap modules.pcimap modules.usbmap net pcmcia scsi usb video 表1
表一列出了LKM相关的文件和目录。其中只有modules.dep、modules.pcimap、modules.isapnpmap、modules.usbmap不是目录。这些实际上是系统内的LKM的列表。让我们看看net目录下的文件(不完全):
3c59x.o 3c90x.o 82596.o 8390.o ac3200.o acenic.o arlan-proc.o 表2
从这个列表中我们可以得到几点信息。第一,模块名字是一.o结尾,为何?因为它们是包含模块内容的目标文件。第二,这个列表并不完全,因为没有足够的空间来写出它的全部内容。
我们要注意的第二个重要的文件是/etc/conf.modules。这个文件让系统管理员为加载模块定义不同的参数。conf.modules文件的语法看起来象这样:
alias parport_lowlevel parport_pc
conf.modules允许系统管理员定义通常使用的模块的别名。注意:这个文件并非系统必需的。一个系统管理员可以定义字节的配置文件。一个系统管理员可以使用modprobe -C命令来完成这项工作。
因为我前面讲到了modprobe命令,所以让我们大体看看modprobe和Linux中其它LKM的管理工具。modprobe命令用来加载一个或者多哥模块,它使用modules.dep文件来检查模块之间的依赖关系。depmod程序产生语法类似于Makefile的依赖关系文件。我要讲的最后三个工具是:lsmod、insmod、rmmod。lsmod为系统管理员提供当前内核加载的LKM的列表,这个列表也可以在/proc/modules中看到。如果你想知道当前正在运行的有哪些内核,这个工具会有所帮助。不过,后面你将看到lsmod对于检查rootkit LKM并不有效。insmod用来加载LKM。有些特洛伊LKM就是使用insmod -f命令来加载特洛伊模块。rmmod用来卸载正在运行的LKM,不过通常rmmod对于rootkit LKM是无效的。稍后,我们将讲述细节。本节我讲了LKM的基础知识,具体请参考http://www.kernel.org
3.LKM rootkit 和KSTAT
最近,一个LKM rootkit(adore)引起了广泛的注意。adore蠕虫不是LKM adore。我在此要讨论的是LKM adore,关于adore蠕虫已经有人分析了。从下面这个网址可以下载这个adore rootkit:http://packetstorm.securify.com/filedesc/adore-0.34.html
adore是一个Linux LKM rootkit。非常易于安装,在配置时只需要很小的调整。可以使用默认的配置来安装adore,用户还可以对其代码做某些修改。其readme文件建议修改ELITE_CMD和HIDDEN_PORT来改变设置。当运行./configure时,它会要求你输入一个密码。这个密码是使用后门端口时,做验证用。如果你需要了解更多的信息,就下载一个吧。运行make后,你可以看到两个文件--ava、startadore。需要运行startadore文件来启动adore。一旦启动adore,就可以使用ava了,下面是运行./ava的输出:
Usage: ./ava {h,u,r,R,i,v,U} [file, PID or dummy (for U)] h hide file u unhide file r execute as root R remove PID forever U uninstall adore i make PID invisible v make PID visible 表4.AVA的输出
上面这个表是adore为使用者提供的功能选项。在此,我不对这些功能做过多解释,因为这对于我们的检测没什么帮助。现在我们要讨论一些adore(LKM)的基础知识,以及如何检测adore等LKM rootkit。
许多rootkit能够隐藏进程、目录、文件甚至连接。但是,这些很多是通过修改一些程序例如:ps、df、netstat、top和lsof的二进制文件。有很多方式可以检测到这种rootkit,例如:t0rn。
- MD5校验
- 用可靠的地方(例如:CD-ROM)的源代码重新编译程序
- 一些rootkit使用默认端口,能够引起系统管理员的注意。
- 使用如chkrootkit之类的程序。
这些技术检测t0rn之类的rootkit可以,但是用来检测LKM rootkit是无效的。因为LKM rootkit是在内核层隐藏进程、连接、目录和文件,它不修改程序二进制文件,因此MD5校验也就无效了。检查端口可能好使,不过它最多只能告诉你已经被rooted了。
那么,如何才能LKM rootkit呢?好办,在此我强烈推荐一个程序KSTAT,它可以很好地完成这项任务。在检查内存时,KSTAT使用/dev/kmem文件获得系统的信息。这就是KSTAT的输出:
Usage: kstat [-i iff] [-P] [-p pid] [-M] [-m addr] [-s] -i iff may be specified as 'all' or as name (e.g. eth0) displays info about the queried interface -P displays all processes -p pid is the process id of the queried task -M displays the kernel's LKMs' linked list -m addr is the hex address of the queried module displays info about the module to be found at addr -s displays info about the system calls' table
你看到了,KSTAT为用户提供了许多选项来检测rootkit。通过讲述这些选项,你可以知道如何检测这些LKM rootkit:knark、adore和rkit。
BTW,如果我忽略了一些LKM rootkit,将在以后补上。kstat -s恐怕是检测LKM rootkit最好的方式。其它的选项也是很不错的,但是kstat -s在任何时候都是有效的。这就是kstat -s的输出:
SysCall Address sys_exit 0xc0117ce4 sys_fork 0xc0108ebc sys_read 0xc012604c sys_write 0xc0126110 sys_open 0xc0125c10 sys_close 0xc0125d60 sys_waitpid 0xc0117ff8 sys_creat 0xc0125ca4 sys_link 0xc012de60 sys_unlink 0xc012dc90 sys_execve 0xc0108f18 sys_chdir 0xc01254a0 sys_time 0xc01184b4 sys_mknod 0xc012d77c sys_chmod 0xc01256e4 表5.kstat -s输出
表5不太完全,但是给了我们一个大体的印象。记住,-s选项为我们提供了一个系统调用表sys_call_table的图。后面我们将再次涉及这些内容。
kstat -P是另一个很有效的选项。这个选项列出当前在系统中运行的所有进程。包括被LKM rootkit隐藏的进程。表6是一个输例子:
PID PPID UID GID COMMAND 1 0 0 0 init 2 1 0 0 kflushd 3 1 0 0 kupdate 4 1 0 0 kpiod 5 1 0 0 kswapd 6 1 0 0 mdrecoveryd 241 1 1 0 portmap(注意) 256 1 0 0 lockd 257 256 0 0 rpciod 266 1 0 0 rpc.statd 280 1 0 0 apmd 331 1 0 0 syslogd 表6.kstat -P
当第一次运行kstat时,我对它所说的功能有所怀疑,但是后来我的疑虑被消除了。下面我们来试试这个功能选项。我首先运行ava -i 241,这个命令用来隐藏portmap进程。接着我运行kstat -P,输出就是表6。然后,我运行ps -ef,没有发现portmap。lsof也不能发现。表7是ps -ef的输出:
UID PID PPID C STIME TTY TIME CMD root 1 0 0 Mar30 ? 00:00:06 init [3] root 2 1 0 Mar30 ? 00:00:00 [kflushd] root 3 1 0 Mar30 ? 00:00:00 [kupdate] root 4 1 0 Mar30 ? 00:00:00 [kpiod] root 5 1 0 Mar30 ? 00:00:00 [kswapd] root 6 1 0 Mar30 ? 00:00:00 [mdrecoveryd] root 256 1 0 Mar30 ? 00:00:00 [lockd] root 257 256 0 Mar30 ? 00:00:00 [rpciod] root 266 1 0 Mar30 ? 00:00:00 rpc.statd root 280 1 0 Mar30 ? 00:00:00 /usr/sbin/apmd -p 10 -w 5 -W -s root 331 1 0 Mar30 ? 00:00:00 syslogd -m 0 root 340 1 0 Mar30 ? 00:00:00 klogd nobody 354 1 0 Mar30 ? 00:00:00 identd -e -o nobody 357 354 0 Mar30 ? 00:00:00 identd -e -o nobody 359 357 0 Mar30 ? 00:00:00 identd -e -o nobody 360 357 0 Mar30 ? 00:00:00 identd -e -o nobody 361 357 0 Mar30 ? 00:00:00 identd -e -o daemon 372 1 0 Mar30 ? 00:00:00 /usr/sbin/atd root 386 1 0 Mar30 ? 00:00:00 crond root 404 1 0 Mar30 ? 00:00:00 inetd root 418 1 0 Mar30 ? 00:00:00 lpd root 462 1 0 Mar30 ? 00:00:00 sendmail: accepting connections root 477 1 0 Mar30 ? 00:00:00 gpm -t ps/2 root 491 1 0 Mar30 ? 00:00:01 httpd xfs 531 1 0 Mar30 ? 00:00:00 xfs -droppriv -daemon -port -1 root 571 1 0 Mar30 tty1 00:00:00 login -- root root 572 1 0 Mar30 tty2 00:00:00 /sbin/mingetty tty2 root 573 1 0 Mar30 tty3 00:00:00 /sbin/mingetty tty3 root 574 1 0 Mar30 tty4 00:00:00 /sbin/mingetty tty4 root 575 1 0 Mar30 tty5 00:00:00 /sbin/mingetty tty5 root 576 1 0 Mar30 tty6 00:00:00 /sbin/mingetty tty6 nobody 4290 491 0 Apr01 ? 00:00:00 httpd nobody 4291 491 0 Apr01 ? 00:00:00 httpd nobody 4292 491 0 Apr01 ? 00:00:00 httpd nobody 4293 491 0 Apr01 ? 00:00:00 httpd nobody 4294 491 0 Apr01 ? 00:00:00 httpd nobody 4295 491 0 Apr01 ? 00:00:00 httpd nobody 4298 491 0 Apr01 ? 00:00:00 httpd nobody 4299 491 0 Apr01 ? 00:00:00 httpd root 8073 571 0 Apr02 tty1 00:00:00 -bash root 10659 8073 0 11:24 tty1 00:00:00 ps -ef 表7.ps -ef的输出
我们还要关注两个功能选项:-p和-M。kstat -p可以给出某个进程更多的信息。要使用kstat -p首先要给出进程的id,例如,kstat -p 241。它能够为我们提供更多的信息,表8是kstat -p 241的输出:
Name: portmap State: S (sleeping) Pid: 241 Ppid: 1 (init) Uid: 1 1 1 1 Gid: 0 0 0 0 Flags: PF_FORKNOEXEC PF_SUPERPRIV Crucial Capabilities Check Open Files 0 CHAR /dev/null 1 CHAR /dev/null 2 CHAR /dev/null 3 0.0.0.0:111 0.0.0.0:0 4 0.0.0.0:111 0.0.0.0:0 7 FIFO /// 8 FIFO /// 21 CHAR /dev/null 表8.kstat -p 241的输出
最后,来看一下kstat -M。通常情况下,系统管理员可以使用lsmod甚至/proc/modules发现他/她的系统中有哪些LKM在运行。但是,如果系统被rooted,lsmod提供的信息就不可信了。kstat -M可以捕捉到许多LKM rootkit的基本信息,列出系统所有已经加载的模块。
4.检测knark、adore和其它的LKM rootkit
上面我们分别讨论了LKM、rootkit和KSTAT。现在我们将把这些结合起来,检测一些LKM rootkit。
第一个就是knark,它可能是最为出名的LKM rootkit,也是写的最好的之一。使用stat来检测它简直易如反掌。记住表5了吗?检测LKM rootkit之前,首先要运行kstat -s。一旦运行了kstat -s就回得到下面的输出:
sys_fork 0xc284652c WARNING! Should be at 0xc0108c88 sys_read 0xc2846868 WARNING! Should be at 0xc012699c sys_execve 0xc2846bb8 WARNING! Should be at 0xc0108ce4 sys_kill 0xc28465d4 WARNING! Should be at 0xc01106b4 sys_ioctl 0xc2846640 WARNING! Should be at 0xc012ff78 sys_settimeofday 0xc2846a8c WARNING! Should be at 0xc0118364 sys_clone 0xc2846580 WARNING! Should be at 0xc0108ca4 表9.检测knark
让我们仔细研究一下表9是什么意思。首先,我们看到系统调用表sys_call_table的7个入口被修改了。看一下sys_settimeofday,输出显示其地址是0xc2846a8c,而kstat -s警告这个系统调用的地址应该是在0xc0118364。knark安装后,它修改了sys_call_table,造成sys_fork、sy_read、sys_execve、sys_kill、sys_ioctl、sys_settimeofday和sys_clone的地址发生了改变。这样就可以检测到knark。知道sys_call_table的哪些入口被修改,有助于确定系统被那种rootkit侵入。knark修改了7个。接着,就是运行ps -ef和kstat -P,对两者的输出做对比。如果有不同,就要采取相应的措施。注意:系统调用的地址随系统的不同而有所不同。
下面看一下adore改变的系统调用地址。
sys_fork 0xc4051428 WARNING! Should be at 0xc0108c88 sys_write 0xc4051590 WARNING! Should be at 0xc01269b8 sys_close 0xc405163c WARNING! Should be at 0xc01264a4 sys_kill 0xc40514d0 WARNING! Should be at 0xc011060c sys_mkdir 0xc405172c WARNING! Should be at 0xc012e540 sys_clone 0xc405147c WARNING! Should be at 0xc0108ca4 sys_getdents 0xc40512a4 WARNING! Should be at 0xc013022c 表10.检测adore
adore也修改了7个系统调用的地址。不过,和knark相比只有3个相同。这有助于我们的区分。下面的步骤和上面相同。
最后,看一下rkit。这个rootkit不使用上面两个rootkit的方式隐藏自己,只修改sys_setuid系统调用。因此,使用kstat -M就可以发现。
5.结论
LKM rootkit对网络管理员来说,简直就是噩梦。它们非常难以发现,但是使用象kstat之类的工具,并且理解它们都造成什么变化,一切都变的容易了。kstat会对系统管理员有所帮助。
6.资源
Kstat
http://s0ftpj.org/en/site.html
Knark
http://members.prestige.net/tmiller12/papers/KNARK.htm
rootkits
http://packetstorm.securify.com/groups/thc/LKM_HACKING.html