Mac OS X 内核Rootkit开发指南

本文详细介绍了Mac OS X操作系统上内核Rootkit的开发过程,包括Rootkit的基础、系统调用原理、内核空间与用户空间交互、XNU内核结构、内核扩展开发以及如何实现系统调用替换。文章通过实例展示了如何在内核中隐藏文件、进程,以及如何通过KUNCExecute函数执行用户空间程序,强调了Rootkit与反Rootkit之间的对抗。
摘要由CSDN通过智能技术生成
                1.引言 

1.1 背景介绍 

        困 扰着不同操作系统的Rootkit已经由来已久,Linux,Windiws,还有各种类BSD等系统都受到了Rootkit的极大危害。目前广泛使用的 一类“内核Rootkit”,是原来“文件转移Rootkit”的衍生和发展。这种发展趋势的必然性,来源于Rootkit和Osiris、 Tripwire等安全软件之间的竞争——后者的出现使得Rootkit开发者不得不在内核空间中寻找更加隐秘的途径,以达到渗透和颠覆系统的目的。 
        Rootkit 是以后门(backdoor)或者嗅探程序(sniffer)等形式存在的恶意代码,其基本行为表现为篡改标准工具和命令的行为与输出。就像计算机安全领 域的其他分支一样,Rootkit与Anti-Rootkit之间总存在着“你高一尺,我高一丈”的对立竞争关系,而且随着技术的发展,这场竞争已经愈演 愈烈。 
        在本文中,以向读者引导和介绍在一个特定系统上实现Rootkit的具体方法为目的,我们将在Apple的Mac OS X操作系统上实现一个运行时内核补丁,完成一个内核级的Rootkit。Apple的Mac OS X系统支持两种不同的CPU架构,即Intel和PowerPC体系。我们实现的Rootkit是体系结构无关的,大部分代码在两种架构下都可以兼容运 行。 

1.2 Rootkit基础 

        Rootkit的目的之一是隐藏自身,因此内核级的Rootkit一般都具有隐藏文件、进程和网络套接字通信的能力,而高级一些的甚至具有后门和和键盘嗅探的功能。 
        当 一个程序,如“/bin/ls”需要列出一个目录下的所有文件时,它会调用内核中的系统调用函数。随着getdirentries()的函数运行,控制流 程从用户空间转移到内核空间,由内核完成用户的请求操作。最终getdirentries()再将特定目录下的文件列表信息返回到用户空间,呈现在用户面 前。 
        为了达到从getdirentires()返回的信息中隐藏特定文件的目的,我们需要修改系统调用返回的文件信息,并在 其到达用户空间之前将特定的条目删除。要实现这个功能有多种选择,一是修改文件系统的处理层,例如虚拟文件系统(VFS)等;二是直接修改目标所指的 getdirentires()函数。相对前者,修改系统调用要简单一些,这也是我们所倾向采用的方法。 

1.3 系统调用基础 

        当 用户空间的程序需要调用内核空间的函数时,它就要唤起(invoke)一个系统调用。系统调用可以看作是提供了特定内核服务的API函数,如文件读写,打 开关闭网络连接等等。每一个系统调用都有唯一的编号,称为系统调用号,在唤起时就是通过编号来判断调用的具体函数。 
        当一个用 户空间的进程需要调用内核函数时,总是先调用一个在libc库中的包装函数,由它产生软件中断,将控制流从用户空间转移到内核。内核在一个称作“系统调用 表”的地方,保存了一份可用的系统调用函数列表,每一个入口项都有一个函数指针,指向编号所对应的系统调用的函数位置。届时,内核将在系统调用表中查找编 号所指的函数入口,并交由后者来处理用户空间的请求。完整的系统调用列表可以在/usr/include/sys/syscall.h文件中找到。如果 Rootkit想要隐藏什么文件,只需关注下面几个系统调用函数就可: 

196 - SYS_getdirentries 
222 - SYS_getdirentriesattr 
344 - SYS_getdirentries64 

        上 述的每一个入口都指出了和列出文件有关的内核函数的地址。SYS_getdirentries是一个先前就有的函数版 本,SYS_getdirentriesattr与前者类似,带有对MAC OS X的特征支持,而SYS_getdirentries64则是较新的版本,支持更长的文件名。通常情况下,SYS_getdirentries由bash 使用,ls用的是SYS_getdirentries64,而SYS_getdirentriesattr则只能由OS X集成的应用程序,如Finder等来使用。在实现Rootkit时,为了向端用户提供统一的输出口径,这其中的每一个函数都要被替换掉。 
        为了实现修改函数输出的功能,设计一个能够替换原始函数的包装函数是十分必要的。包装函数首先调用原始的函数,搜索其输出,做必要的修改和验证之后再返回到用户空间。 

1.4 用户空间与内核空间 

        就 像用户空间的进程有其私有独立的内存地址一样,内核也是在相对独立的地址空间中运行的。这同时意味着在内核中想要自由、不受约束的读写内存地址是不可能实 现的了。当内核空间的程序想要修改用户空间的地址,如拷贝数据到用户空间时,就需要遵守特定的协议和处理例程。好在为了完成特定的任务,有相当数量的辅助 函数可以参考和借鉴,在这里我们就可以使用copyin和copyout这两个函数。 



2 XNU内核介绍 

        Mac OS X操作系统的内核叫做XNU,其核心是基于Mach微内核与FreeBSD 5而实现的。系统在Mach层,负责内核线程、进程、多任务调度、消息传递、虚拟内存管理以及控制台IO等多项任务;接着Mach之上的是BSD层,提供 了与POSIX标准相兼容的API,网络功能,以及文件系统等等。XNU内核采用了一个称之为“I/O Kit”的面向对象框架来实现设备驱动程序的加载和卸载,它既可以将不同的技术糅合在一起为同样的目的服务,也为修改操作系统提供了一条的简便途径。除此 之外,XNU内核还有一个有趣的事情,内核和用户空间都使用各种独立的4GB的地址空间,和我们在其他操作系统中见到的好像不太一样。^_^ 

2.1 OS X内核Rootkit的历史 

        目 前已知的在Mac OS X系统上发布的最早内核Rootkit是WeaponX,由nemo开发,出现于2004年11月份。它采用了和大多数Rootkit一样的内核扩展(可 加载内核模块,LKM)技术,提供了内核Rootkit的各项基本功能。然而WeaponX的兼容性不是很好,随着后来Mac OS X内核的调整,在新系统上也就不能再正常工作了。 
        在最近发布的几个Mac OS X的版本中,Apple作了很多工作,加强了内核防护,让系统渗透变得困难了许多。更令人感到沮丧的是,系统调用表等重要的内核结构,都不再向开发者公开其具体细节,此时开发Rootkit的工作更是显得难上加难。 

2.2 寻找系统调用表 

        版 本号为10.4的OS X系统已经没有导出的内核符号表的存在,这意味着编译器将无法自动确定系统调用表在内存中的存放位置了。此时,可以迂回的,采用在内存空间中强力搜索,或 者寻找其他参照物的方法来解决这个问题。Landon Fuller发现的一条简便途径,系统的输出符号之一nsysent(系统调用表中的入口数目)就位于和系统调用表临近的某个位置,用特殊的程序就将其找 到并返回一个指向系统调用表的指针,具体细节可以参 http://landonf.bikemonkey.org/code/macosx/Leopard_PT_DENY_ATTACH.20080122.html  。最终,我们得到了系统调用表入口项的数据结构如下: 

struct sysent { 
int16_t                sy_narg;                                /* number of arguments */ 
int8_t                reserved;                                /* unused value */ 
int8_t                sy_flags;                                /* call flags */ 
sy_call_t                *sy_call;                                /* implementing function */ 
sy_munge_t        *sy_arg_munge32;                /* system call arguments for32-bit processes */ 
sy_munge_t        *sy_arg_munge64;                /* system call arguments for 64-bit processes */ 
int32_t                sy_return_type;                /* return type */ 
uint16_t                sy_arg_bytes
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值