使用KSAT检测可加载内核模块

简介: 使用KSAT检测可加载内核模块 1.目的 本文包括LKM基础,如何检测LKM。 2.LKM 什么是LKM?LKM是可加载内核模块的缩写,就是那些包含动态可加载部分的文件。


使用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。

  1. MD5校验
  2. 用可靠的地方(例如:CD-ROM)的源代码重新编译程序
  3. 一些rootkit使用默认端口,能够引起系统管理员的注意。
  4. 使用如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

目录
相关文章
|
4月前
|
NoSQL Linux Android开发
内核实验(三):编写简单Linux内核模块,使用Qemu加载ko做测试
本文介绍了如何在QEMU中挂载虚拟分区、创建和编译简单的Linux内核模块,并在QEMU虚拟机中加载和测试这些内核模块,包括创建虚拟分区、编写内核模块代码、编译、部署以及在QEMU中的加载和测试过程。
231 0
内核实验(三):编写简单Linux内核模块,使用Qemu加载ko做测试
|
3月前
内核模块加载流程图
内核模块加载流程图
将模块编译入内核
将模块编译入内核
113 0
|
安全 测试技术 Windows
HEVD内核攻击:驱动程序的编译、安装、加载及调试(一)
本文讲的是HEVD内核攻击:驱动程序的编译、安装、加载及调试(一),HEVD是HackSys的一个Windows的训练项目,是一个存在漏洞的内核的驱动,里面存在多个漏洞,通过ControlCode控制漏洞类型,这个项目的驱动里几乎涵盖了内核可能存在的所有漏洞
1769 0