首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>linux 内核>文章内容
Linux可加载内核模块:入侵响应分析
来源: 作者: 发布时间:2007-08-26  

现在的网络安全入侵,无处不在,如果你的系统被入侵了,而你在入侵事件日志调查中,传统的工具完全失效了,你该怎么办?当我在对付入侵者已经加载的内核模块时,就陷入了这种困境。由于从用户空间升级到了内核空间,LKM方式的入侵改变了以往使用的入侵响应的技术。一旦内核空间遭破坏,影响把覆盖到整个用户空间,这样入侵者无须改动系统程序就能控制他们的行为。而用户即使把可信的工具包上传到被入侵的主机,这些工具也不再可信。下面我把揭示恶意的内核模块怎么样工作,并且给出一些我开发的对付此类入侵的工具。

LKM概述

LKM的存在对系统管理员是个福音,对入侵检测却是个噩梦。lkm最初被设计用来无须重新启动而改变运行中的内核,从而提供一些动态功能。动态内核提供了对诸如新文件系统类型和网卡等设备的额外支持。此外,由于内核模块能够访问内核的所有调用和存储区,它能不受控制地改动整个操作系统的各个部位,因而所有调用和内存常驻的结构都有被恶意内核模块修改的危险。

lkm的一个臭名昭著的例子是knark。一旦knark编译并加载到入侵主机,把改变系统调用表从而改变操作系统的行为。系统调用表常驻在内核空间,基本上是提供给用户级别程序访问操作系统的入口。大多数unix系统在手册的第二部分给出syscalls的正式定义。一旦内核作为用户空间运行,OS把把命令行上运行的所有命令和调用映像到系统调用表中。因此当knark改变系统调用表时也就改变了用户命令的执行。knark改动了以下的重要系统调用。

* getdents - 获得目标路径的目录项内容(即文件和子目录)。通过修改这个调用,knark实现对用户程序隐藏文件和目录。

* kill - 向进程发送信号,通常是杀掉进程。修改过的调用把使用无用的信号31,触发设置进程为"hidden"状态。当进程在hidden状态时,它在/proc中的纪录被删除,从而实现了对ps命令隐身。信号32被用来解除隐藏状态。

* read - 读取目标文件的内容。knark通过修改此调用实现对netstat隐藏入侵者的连接。

* ioctl - 改变文件和设备的状态。通过修改此调用,knark能够隐藏网卡的混杂位,同时在调用中插入了隐藏文件的函数。

* fork - 派生新进程。knark修改用来隐藏一个隐藏的父进程所派生的所有子进程。

* execve - 执行一个程序。每次用户在命令行下输入命令时调用。一旦此调用被劫持,内核模块可以控制命令的选择和运行。knark使入侵者可以把一个程序指向另一个,如同符号连接一样,而不留下罪证。knark控制了execve后,任何你希望执行的程序都有可能是入侵者的替代品。

* settimeofday - 设置系统时间。knark用来监控预定的时间。当这些预定时间之一被送给此系统调用时,knark可以触发某些管理任务或者立即赋予当前用户root的用户和组id。这样就无需更改到suid的shell而直接获得root权限。

由于系统调用被更改,那些管理工具的功能也被更改了。netstat把永远不报告网卡的混杂模式,来自特定地点的连接也被隐藏。ps和top命令不会报告隐藏的进程,因为/proc中没有信息。ls把跳过隐藏的文件和目录。所有这些,都是因为此类工具依靠操作系统提供信息,而入侵者在控制了操作系统后就能够向来自用户空间的请求反馈虚假情报,并且无需改动netstat,ps,top和ls程序的二进制文件。因此,tripwire一类的文件系统校验工具对这类工具把失效,也无法防备knark的执行重定向功能。如果入侵者把hackme连接到cat上,每次cat被调用,实际上是hackme在执行。这样,cat仍然保留在系统上,md5校验码也没有改变,但执行的功能却改变了。

更糟糕的是,把一套新的工具上传到被knark入侵的主机也无济于事。即使是可信的工具一样要使用系统调用,于是他们也变得不再可信。目前还无法绕过入侵者在内核级别的陷阱,除非我们也进入内核空间。基于此,我开发了检测系统是否安装了恶意LKM的工具。

之前有一点我们没有提及,lsmod会报告装载了knark.o模块。不幸的是,入侵者能轻易的把此信息抹去。knark同时还包括了另一个LKM叫做modhide,能够隐藏自身以及上一个模块。一旦模块隐藏,如果不重启动机器就无法卸载,而且没有简单的方法检测到模块的加载,所有的相关信息都不见了。正如之前介绍的,knark的所有功能令其成为终极秘密武器。

预防方法

阻止LKM破坏显然是最佳解决方案。我们有几种方法能够提前预防lkm。可以通过保护系统调用表来预防大部分的恶毒lkm。我们可以构造一个简单的lkm,定时的或者在其他模块加载时监控系统调用表。如果它发现系统调用表改变了,可以通知系统管理员甚至把调用表修改回原来的值。下面的例子能很好的工作在linux 2.2和2.4上。如果你的机器有超过一个处理器,可以用如下命令编译:gcc -D __SMP__ -c syscall_sentry.c。如果是单处理器,去掉-D __SMP__就行了。编译成功后,用insmod加载。

(the end)


 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·使用 Linux 系统调用的内核命令
·Linux 2.6.11内核文件IO系统调用
·Linux操作系统的源代码目录树结
·Linux用户态与内核态的交互讲解
·Linux内核对I/O端口的管理实现(
·深入分析 Linux操作系统的内核链
·Linux内核可装载模块对设备驱动
·概述Linux系统的驱动框架及驱动
·详解Linux 2.6内核新文件系统变
·Linux系统可卸载内核模块完全指
·FreeBSD手册讲解(一)--配置FreeB
·编译Linux操作系统的内核讲解
  相关文章
·调整内核网络参数提高Linux系统
·概述Linux系统的驱动框架及驱动
·Linux 2.6新内核的设计理念及新
·Linux内核重编译常见故障及其解
·Linux用户态与内核态的交互讲解
·FreeBSD手册讲解(二)—配置FreeB
·FreeBSD手册讲解(一)--配置FreeB
·一种内核到用户空间的高效数据传
·Linux系统内核新型包过滤结构的
·编译支持NTFS的Linux系统内核模
·Linux操作系统动态函式库讲解(二
·Linux操作系统动态函式库讲解(

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!