lseek(kmemh, strtoul(argv[1], NULL, 16), SEEK_SET);
/*写入我们的补丁字节*/
write(kmemh, &asmcode, 1):
close(kmemh);
}
让我们总结一下我们现在所知道的:我们能够改变任何内核符号;这包括一些像sys_call_table[]这样的东西,更有其他任何的函数或结构。记住每个内核补丁只有在我们能够存取到/dev/kmem的时候才能够使用。但是我们也知道了如何保护这个文档。能够看3.5.5。
###adv### 4.2.1 如何在/dev/kmem中找到内核符号表
在上面的一些基本的例子过后,您也许会问如何更改任何一个内核符号连同如何才能找到有趣的东西。在上面的例子中,我们使用/proc/ksyms来找到我们需要改变的符号的地址。但是当我们在一个内核里面没有LKM支持的系统时该怎么办呢?这将不会有/proc/ksyms这个文档了,因为这个文档只用于管理模块。(公共的,或存在的符号)。那么对于那些没有输出的内核符号我们该怎么办呢?我们怎样才能更改他们?
呵呵,有很多问题。现在让我们来找一些解决的方案。Silvio Cesare讨论过一些发现不同的内核符号的方法(公共的或不公开的)。他指出当编译Linux内核的时候,一个名字叫System。map的文档被创建,他映射每一个内核的符号到一个固定的地址。这个文档只是在编译的时候解析这些内核的符号的时候才需要。运行着的系统没有必要使用这个文档。这些编译时候使用的地址和/dev/kmem里面使用的使相同的。因此,通常的步骤是:
查找system。map来获得需要的内核符号
找到我们的地址
改变内核符号(结构,函数,或其他的)
听上去相当的容易。但是这里会有一个大问题。每一个系统并不使用和我们相同的内核,因此他们的内核符号的地址也不会和我们的相同。而且在大多数系统中您并不会找到一个有用的system。map文档来告诉您每一个地址。那我们应该怎么办呢?Silvio Cesare建议我们使用一种关键码搜寻的方法。只要使用您的内核,读一个符号的开始的十个字节的(是随机的)值,并且把这十个值作为关键码来在另一个内核中搜寻地址。假如您不能为某个符号找到一个一般的关键码,您能够尝试找到这个符号和系统其他您能够找到关键码的符号的关系。要找到这种关系您能够看内核的源代码。通过这种方法,您能够找到一些您能够改变的有趣的内核符号。(补丁)。
4.2.2 新的无需内核支持的'insmod'
现在到了我们回到我们的LKM入侵上的时候了。这一节将会向您介绍Silvio Cesare的kinsmod程式。我只会列出大体上的工作方法。这个程式的最为复杂的部分在于处理(elf文档)的目标代码和内核空间的映射。但是这只是个处理elf头的问题,不是内核问题。Silvio Cesare使用elf文档是因为通过这种方法您能够安装[正常]的LKMs。当然也能够写一个文档(仅仅是操作码-〉看我的RET例子)并且插入这个文档,这会有点难,但是映射会很容易。对于那些想真正理解elf文档处理的,我把Silvio Cesare的教材加进来了。(我已做了,因为Silvio Cesare希望他的源代码或想法只能在那份教材里面作为一个整体传播)。
现在让我们来看看在一个没有LKM支持的系统中插入LKM的方法。
假如我们想插入代码(一个LKM或其他的任何东西),我们将要面对的第一个问题是如何获得内存。我们不能取一个随机的地址然后就往/dev/kmem 里面写我们的目标代码。因此我们必须找到一个放我们的代码的地方,他不能伤害到我们的系统,而且不能因为一些内核操作就被内核释放。有一个地方我们能够插入一些代码,看一眼下面的显示任何内核内存的图表:
kernel data
...
kmalloc pool
Kmalloc
pool是用来给内核空间的内存分配用的(kmalloc(...))。我们不能把我们的代码放在这里,因为我们不能确定我们所写的这个地址空间是没有用的。现在看看Silvio Cesare的想法:kmalloc pool在内存中的边界是存在内核输出的memory_start和memory_end里面的。(见/proc/ksyms)。有意思的一点在于开始的地(memory_start)并不是确切的kmalloc pool的开始地址。因为这个地址要和下一页的memory_start对齐。因此,会有一些内存是永远都不会被用到的。(在memory_start和真正的kmalloc pool的开始处)。这是我们插入我们的代码的最好的地方。OK,这并不是任何的一切。您也许会意识到在这个小小的内存空间里面放不下任何有用的LKM。 Silvio Cesare把一些启动代码放在这里。这些代码加载实际的LKM。通过这个方法,我们能够在缺乏LKM支持的系统上加载LKM。请阅读Silvio Cesare的论文来获得进一步的讨论连同如何实际上将一个LKM文档(elf 格式的)映射到内核。这会有一点难度。
4.3 最后的话
第二节的主意很好。但是对于那些不允许存取kmem的系统呢?最后的一个方法就是利用一些内核系统漏洞来插入/改变内核空间。在内核空间总是要有一些缓冲区溢出或其他的毛病。还要考虑到一些模块的漏洞。只要看一眼内核的许多源文档。甚至用户空间的程式也能够帮助我们改变内核。
我还记得,在几个星期以前,一个和svgalib有关的漏洞被发现。每一个程式通过使用svgalib来获得一个向/dev/mem的写权限。 /dev/mem也能够被RKP用来获得和/dev/kmeme相同的地址。因此看一看下面的列表,来获得一些如何在一个很安全的系统中做RKP的方法:
找到一个使用svgalib的程式。
检查那个程式,获得一个一般的缓冲区溢出(这应该并不会太难)
写一个简单的程式来启动一个程式,打开/dev/mem,获得写句柄,并且能够操纵任务结构使得您的进程的UID=0
###adv### 创建一个root的shell
这个机制通常运行的很好(zgv,gnuplot或其他的一些著名的例子)。为了获得这个任务结构一些人使用下面的Nergal的程式(这是使用了打开写句柄的)
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




