将Linux操作系统用于服务器在现在是越来越普遍了。因此,入侵Linux在今天也变得越来越有趣.现在最好的攻击Linux的技术就是修改内核代码.由于一种叫做可卸载内核(Loadable
KernelModules(LKMs))的机制,我们有可能编写在内核级别运行的代码,而这种代码能够允许我们接触到操作系统中很敏感的部分.在过去有一些很好的关于LKM知识的文本或文档,他们介绍一些新的想法,方法连同一名Hacker所梦寐以求的完整的LKMs.而且也有一些很有趣的公开的讨论(在新闻组,邮件列表).
然而为什么我再重新写这些关于LKMs的东西呢?下面是我的一些理由:
在过去的教材中常常没有为那些初学者提供很好的解释.而这个教材中有很大一部分的基础章节.这是为了帮助那些初学者理解概念的.我见过很多人使用系统的缺陷或监听器然而却丝毫不了解他们是如何工作的.在这篇文章中我包含了很多带有注释的源代码,只是为了帮助那些认为入侵仅仅是一些工具游戏的初学者!
每一个发布的教材但是把话题集中在某个特别的地方.没有一个完整的指导给那些关注LKMs的Hacker.这篇文章会覆盖几乎任何的关于LKMs的资料(甚至是病毒方面的).
这篇文章是从Hacker或病毒的角度进行讨论的,但是系统管理员或内核的研发者也能够参考并从中学到很多东西.
以前的文章介绍一些利用LKMs进行入侵的长处或方法,但是总是更有一些东西是我们过去从来没有听说过的.这篇文章会介绍一些新的想法给大家.(不是任何的新的资料,只是一些对我们有帮助的)
这篇文章会介绍一些简单的防止LKM攻击的方法,同时也会介绍如何通过使用一些像运行时内核补丁(Runtime Kernel Patching)这样的方法来对付这些防御措施.
要记住这些新的想法仅仅是通过利用一些特别的模块来实现的.要在现实中真正使用他们还需要对他们进行改进.这篇文章的主要目的是给大家在整个LKM上一个大方向上的指导.在附录A中,我会给大家一些实用的LKMs,并附上一些简短的注释(这是为那些新手的),连同如何使用他们.
整篇文章(除了第五部分)是基于 Linux 2.0.x的80x86机器的.我测试了任何的程式和代码段.为了能够正常使用这里提供的绝大部分代码,您的Linux系统必须有LKM支持.只有在第四部分会给大家一些无需LKM支持的源代码.本文的绝大多数想法相同能够在Linux2.2.x上实现(也许您会需要一些小小的改变).
这篇文章会有一个特别的章节来帮助系统管理员进行系统安全防护.您(作为一名Hacker)也必须仔细阅读这些章节.您必须要知道任何系统管理员知道的,甚至更多.您也会从中发现很多优秀的想法.这也会对您研发高级的入侵系统的LKMs有所帮助.
因此,通读这篇文章吧.
第一部分. 基础知识
1.1 什么是LKMs
LKMs就是可卸载的内核模块(Loadable Kernel
Modules)。这些模块本来是Linux系统用于扩展他的功能的。使用LKMs的长处有:他们能够被动态的加载,而且无需重新编译内核。由于这些长处,他们常常被特别的设备(或文档系统),例如声卡等使用。
每个LKM至少由两个基本的函数组成:
int init_module(void) /*用于初始化任何的数据*/
{
...
}
void cleanup_module(void) /*用于清除数据从而能有一个安全的退出*/
{
...
}
加载一个模块(常常只限于root能够使用)的命令是:
# insmod module.o
这个命令让系统进行了如下工作:
加载可执行的目标文档(在这儿是module.o)
调用 create_module这个系统调用(至于什么叫系统调用,见1.2)来分配内存.
不能解决的引用由系统调用get_kernel_syms进行查找引用.
在此之后系统调用init_module将会被调用用来初始化LKM->执行 int inti_module(void) 等等
(内核符号将会在1.3节中内核符号表中解释)
OK,到现在为止,我想我们能够写出我们第一个小的LKM来演示一下这些基本的功能是如何工作的了.
#define MODULE
#include
int init_module(void)
{
printk("<1>Hello World\n");
return 0;
}
void cleanup_module(void)
{
printk("<1>Bye, Bye");
}
您可能会奇怪为什么在这里我用printk(....)而不是printf(.....).在这里您要明白内核编程是完全不同于普通的用户环境下的编程的.您只能使用很有限的一些函数(见1.6)仅使用这些函数您是干不了什么的.因此,您将会学会如何使用您在用户级别中用的那么多函数来帮助您入侵内核. 耐心一些,在此之前我们必须做一点其他的.....
上面的那个例子能够很容易的被编译:
# gcc -c -O3 helloworld.c
# insmod helloworld.o
OK,现在我们的模块已被加载了并且给我们打印出了那句很经典的话.现在您能够通过下面这个命令来确认您的LKM确实运行在内核级别中:
# lsmod
Module Pages Used by
helloworld 1 0
这个命令读取在 /proc/modules 的信息来告诉您当前那个模块正被加载.'Pages'
显示的是内存的信息(这个模块占了多少内存页面).'Used by'显示了这个模块被系统
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




