LoadableKernelModules注射

2008-04-09 04:12:21来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折


==Phrack Inc.== Volume 0x0b, Issue 0x3d, Phile #0x0a of 0x0f |=----------------=[ Infecting loadable kernel modules ]=----------------=|
|=-----------------------------------------------------------------------=|
|=--------------------=[ truff <truff@projet7.org> ]=-------------------=|
|=-----------------------------------------------------------------------=|
|=------------=[ translator: osmose <osmose@ph4nt0m.net> ]=-------------=|
LKM 注射 --[ 内容 1 - 介绍 2 - ELF 基础知识
2.1 - The .symtab section
2.2 - The .strtab section 3 - 玩转 loadable kernel modules
3.1 - 模块加载
3.2 - 修改 .strtab section
3.3 - 插入代码
3.4 - 保持隐蔽性 4 - 实例
4.1 - 最简单的 LKM 感染
4.2 - 我还会回来的 (重启之后) 5 - 关于其他的操作系统
5.1 - Solaris
5.2 - *BSD
5.2.1 - FreeBSD
5.2.2 - NetBSD
5.2.3 - OpenBSD 6 - 结论 7 - 感谢 8 - 参考资料 9 - 源代码
9.1 - ElfStrChange
9.2 - Lkminject
--[ 1 - 介绍 这些年来,很多 rootkit 使用了 loadable kernel modules。这仅仅是一种短暂的流
行现象吗?不是,lkm 的广泛使用得益于它强大的功能:可以隐藏文件,进程还有其他
一些妙用。对于第一代使用 lkm 的 rootkits,使用lsmod命令就可以轻易的找出它们。
我们见过许许多多隐藏模块的手法,比如在Plaguez的文章 [1]里提到的那种,还有更多
的在Adore Rootkit [2]里面用到的技巧。几年以后,我们还看到一些新技术:通过使用
/dev/kmem [3] 修改kernel内存映射(kernel memory image)。最后,参考资料[4]向
我们展示了静态内核补丁(static kernel patching)技术。这个技术解决了一个大问题:
rootkit在机器重启后可以重新加载。 (译者注:查找了一下lsmod的运作方式,供大家了解。"在kernel 2.0.x 时,指令
'lsmod'是去开启档案 '/proc/modules' 来得知系统中,已加载哪些 Module。不过
到了kernel 2.1.x以后,系统提供了函式' query_module'。因此,此时'lsmod'的实
作便是透过呼叫 query_module 来取得系统已加载 module的相关资料。") 本文提出了一种新的隐藏lkm rootkits的技术并且保证这些rootkit在机器重启后能够
重新加载。文章会提到如何感染一个系统使用的内核模块。本文针对的是 Linux kernel
x86 2.4.x 系列,不过这个技术可以在任何使用ELF文件格式的系统中推广。要了解这个
技术需要一些基础知识。内核模块是ELF object 文件,我们需要了解一点ELF格式,尤其
是关于符号命名部分的知识。此后,我们会接着学习模块加载机制以便了解如何把恶意代
码插入内核模块中。最后,实战操作一下模块的插入。 --[ 2 - ELF 基础 Executable(可执行) & Linking(链接) Format (ELF) 是用于linux操作系统上的
可执行文件格式。我们先要了解部分相关知识,以后用得着(如果想要全面了解ELF格式,
请参考[1])。 当链接两个ELF object 文件的时候,链接程序需要知道每个object文件
里相关符号的一些情况。每个ELF object文件(比如lkm的那些object文件)包含了两个
部分(译者注:就是后文的 .symtab 和 .strtab 两个section )。这两个section 是用
来存储每个符号的信息结构的。我们不但要研究它们,还要总结出一些对感染内核模块有
用的思路。
----[ 2.1 - .symtab section 这部分是一个结构列表。当链接程序使用那些ELF object文件里的符号时,就需要这些
数据。在/usr/include/elf.h里可以找到这个结构的定义: /* Symbol table entry. */(符号列表入口) typedef struct
{
Elf32_Word st_name; /* Symbol name (string tbl index) */(符号名(字符串列表索引))
Elf32_Addr st_value; /* Symbol value */(符号的值)
Elf32_Word st_size; /* Symbol size */(符号数据占用空间的大小)
unsigned char st_info; /* Symbol type and binding */(符号类型和绑定)
unsigned char st_other; /* Symbol visibility */(符号的可见性)
Elf32_Section st_shndx; /* Section index */(各section 的索引)
} Elf32_Sym; 这里我们只对st_name感兴趣。实际上它是 .strtab section 的索引,而那些符号的名称就是
存储在 .strtab 里面的。
----[ 2.2 - .strtab section .strtab section 是一个非空字符串的列表。正如我们上面看见的,Elf32_Sym里面的st_name
是 .strtab section 的索引。如果我们寻找的符号在某个字符串里,我们可以很方便的得到这个
字符串的偏移地址。下面是我们的计算公式: offset_sym_name = offset_strtab st_name offset_strtab 是 .strtab section 相对于文件起始处的偏移地址,可以通过section 名称解
析机制获得。这和我们要谈的技术关系不是很大,这里就不深究了。参考资料[5]里面详细探讨了
这个问题,后面章节9.1给出了具体实现的代码。 现在可以说,在ELF object 文件里,我们可以很方便的找到符号名并修改它们。不过修改过程
中始终要牢记一点:.strtab section 是由连续的非空字符串组成的,这对修改后新的符号名是一
个限制:新名称的长度不能超过原来的那个长度,否则会殃及 .strtab 中下一个符号。(译者注:
这里和溢出的道理一样,新名称长度超过原先设定值,多出的部分就会写到后面一个符号名区域里,
覆盖后面有用的部分) 遵守了这一点,我们就能做到简单的修改符号名而不影响模块的正常运行,最终实现用一

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:UNIX下的缓冲区溢出防御体系

下一篇:基于内核的rookit经验