当前位置: 查字典论文网 >> 一种防范Rootkit入侵的内核模块加载机制

一种防范Rootkit入侵的内核模块加载机制

格式:DOC 上传日期:2023-03-22 01:20:44
一种防范Rootkit入侵的内核模块加载机制
时间:2023-03-22 01:20:44     小编:

摘要:内核级Rootkit是破坏内核完整性的最大威胁,它通常通过冒充或篡改合法模块加载到内核。在对内核级Rootkit防范技术进行对比分析的基础上,提出一种认证和检测相结合的内核模块加载机制,该机制将内核模块区分为信任模块和非信任模块,加载前者时首先验证其完整性,加载后者时,验证其身份和完整性,并实时检测其对内核数据的修改。实验表明,该机制能防范内核级Rootkit通过内核模块方式入侵。

关键词:Rootkit;内核级Rootkit;内核模块;Linux

0 引言

在运行系统中动态加载或卸载内核模块是大部分现代操作系统具备的基本功能。 Rootkit是攻击者向计算机系统中植入的、能够隐藏自身踪迹并保留超级用户访问权限的恶意程序[1]。它主要分为用户级和内核级两种,内核级Rootkit可入侵操作系统内核层,通常会在内核空间更改和插入执行代码,它是破坏内核完整性的最大威胁。利用模块机制是内核级Rootkit入侵内核的常用手段。

1 传统模块加载机制安全弱点

内核级Rootkit利用传统内核模块加载机制进入内核的方式主要有两种:一是冒充合法模块,系统管理员使用正常的加载命令将其加载到系统;二是修改静态内核模块文件,待系统重启后加载到系统。研究表明,为了达到入侵目的,其主要修改内核空间的下列关键数据:①系统调用函数;②系统调用表;③系统调用入口函数;④中断描述符表;⑤虚拟文件系统。

2 相关防范技术

2.1 驱动程序签名认证技术

Windows采取驱动程序签名技术防范Rootkit[2]。为防止内核级Rootkit通过驱动程序方式加载到内核,驱动程序厂商首先需从认证中心如erisign申请获得软件发布证书(SPC), 厂商使用SPC对驱动程序签名,签名信息依据驱动程序类别的不同可以作为一个单独的文件存放,也可以嵌入到驱动程序文件映像中,签名后的驱动程序不能再被修改,否则验证签名会失败。当驱动程序加载到内核时,系统会认证驱动程序的证书和签名,只有证书的合法性和驱动程序的完整性验证均通过才能将驱动加载到内核。

2.2 内核密封技术

Linux采用内核密封技术保护内核的安全性[3]。Linux使用一种被称为LIDS的工具保护安全性,LIDS采用能力机制实现了内核密封功能,只允许在系统启动时加载内核模块,系统运行时密封内核,包括root用户在内都不能为系统加载模块。密封内核是通过改变相应的能力位,使执行加载模块的进程都会被拒绝执行。密封内核后,除非利用lidsadm和口令,否则系统不允许改变能力位。

2.3 检测技术

(1)检测文件完整性。部分检测工具通过检测文件的完整性以防范Rootkit,当测定文件被更改时,判定该文件为不安全文件,典型工具如Tripwire和AIDE。Tripwire的工作原理是对每个要监控的文件产生一个数字签名,保留下来,当文件当前的数字签名与保留的数字签名不一致时,则说明现在这个文件必定被改动过了。AIDE通过创建一个指定文件的数据库进行检测,数据库中包含了许多文件的属性,如许可、节点数、用户、组、文件大小、创建时间、修改时间、访问时间等。系统管理员指定对哪些文件和目录进行跟踪加密校验。

(2)检测内核地址。部分检测工具通过检测内核地址来检测是否感染Rootkit,当检测到内核地址发生改变后,判定内核已经感染Rootkit。如Kern_check是一个针对重定向系统调用函数的对Rootkit进行检测的工具,其工作原理是通过比较当前内存中系统调用表(通过/dev/kmem)和Linux内核编译产生原始内核符号表来检测内核级Rootkit,该映射存于系统/boot/system.map,两个表的一些表项值不同表明系统调用函数被重定向。

3 认证与检测相结合的内核模块加载机制

通过对防范内核级Rootkit技术的综合分析可知,防范技术大致可以分为两类:一类是主动型,它要求抬高“门槛”,设置权限,防止内核级Rootkit冒充合法身份进入内核;另一类是被动型,它要求加强监测,通过检测相关数据的变化,判定是否发生Rootkit入侵。从防范手段上看,主动防范可以把不想加载的文件拒之门外,但同时也使合法的模块要加载到内核,也要多一道手续,给用户造成诸多不便;被动防范可以检测相关文件和数据的完整性情况,有助于保护系统认为重要的文件和数据,但被动防范是在Rootkit入侵之后,对系统已经造成了破坏,并且随着更隐秘、更高级的入侵手段的出现,被动防范可能会束手无策。从防范效果上看,两种防范手段各有所长,但随着各种网络攻击手段越来越隐秘,越来越难以防范,两种手段都出现了不能拦截或检测的Rootkit。本文设计一种认证和检测相结合的内核模块加载机制,将两种技术的优点结合起来,从内核模块的身份、完整性、行为3个层面进行防护,切实堵住Rootkit入侵内核的渠道。

3.1 整体框架

本文设计的内核模块加载机制,将内核模块区分为“信任模块”和“非信任模块”。信任模块指那些管理员认为肯定可信的模块,如用于实验的模块、管理员自身开发的驱动程序等。对于“信任模块”,系统不需要验证其身份,只需要验证其完整性,即确认其是否被篡改过。除信任模块之外的模块,就是“非信任模块”,如第三方开发的模块、从互联网上下载的驱动等。在加载“非信任模块”时,要从内核模块的身份、完整性和行为3个层面进行鉴别。验证模块身份,确定模块来源是否可信;验证模块完整性,确定模块是否被非法篡改;验证模块行为,确定内核是否因为加载模块发生异常改变。如图1所示,加载内核模块前,首先查看是否为信任模块,若是,则验证其完整性,不是,则验证模块自身携带的证书确认模块的身份。通过了证书认证,就和信任模块一样,验证其完整性。内核模块加载到内核后,如果该模块不是系统的信任模块,要实时检测内核关键数据的变化情况,如果内核关键数据发生了异常改变,则发出报警信号,由系统管理员决定是否卸载已经加载的模块。

3.2 工程实现方案

上述机制的实现,首先需要一个CA认证中心,用于审定模块开发者资质,向信任的模块开发者颁发证书,并负责证书的管理;其次要有专门的签名工具,用于对模块签名;还要对系统内核进行修改,改变以前的加载流程,引入身份验证、完整性验证、内核数据检测等环节。本文在实验室里初步实现上述环节,简述如下:

(1) 模块签名。可加载内核模块是一种ELF格式的文件,其具体信息包含在每一个被称为“section”的信息块中,如指令信息、数据信息等。模块签名就是模块的开发者使用公开的签名工具对模块打上特定的“烙印”。首先,模块开发者向指定的CA认证中心申请证书,申请证书成功后,基于公开密钥算法为模块签名(如RSA算法),使用某种摘要算法计算模块文件的摘要值(如md5算法),这里的摘要内容是ELF文件中后缀为“.text”和“.data”的section,计算得到的摘要值经过唯一私钥加密,即得到模块的签名信息。如图2所示,签名后的模块增加了两个section,一个是签名信息,一个是开发者向CA认证中心申请的证书。

(2) 信任模块的管理和验证。信任模块是专门为管理系统认为可信的模块所设计的数据结构,包括模块名、模块的摘要值,以及计算模块摘要的算法:

内核初始化时,初始化函数首先读取记录了每一个信任模块信息的配置文件,形成上述数据结构的数据链,即为系统的信任模块管理链。系统管理员可以使用命令查询、增加、删除当前信任模块管理链中的模块。

当某模块请求加载到内核时,系统首先查看该模块名是否存在于本系统的信任模块链上。如果在,则说明它是信任模块,使用登记的计算摘要算法重新计算该模块的摘要,即ELF文件中后缀为“.text”和“.data”的section给的摘要,并与登记的摘要值对比,只有完全一致才允许加载。

(3) 验证非信任模块。对于非信任模块,首先认证模块的证书,认证通过后再认证模块的签名,只有证书和签名的认证都通过,才被判断为可以加载。如图3所示,内核对非信任模块的验证是通过处于内核态的模块加载进程与处于用户态的监听进程交互达到的[4],它们之间的交互通过进程间的通信机制实现。监听进程作为守护进程在系统启动时运行,一直处于监听模式,等待内核态进程发出的认证请求。若当前加载的模块是非信任模块,内核加载进程将发出认证请求,监听进程在收到认证请求后,调用证书服务函数认证指定的模块证书和签名信息,并将认证结果传递给内核,由内核决定是否加载模块。

认证证书的过程就是建立一条从模块自身携带的证书到根证书的证书链,如果能够建立这样一个证书链并且证书链上的证书都是有效的,则通过证书验证,如果不能建立这样一个证书链或者建立的证书链上有的证书已经过期,则不能通过证书验证。通过了证书验证的模块,将进一步验证其签名信息,从已经通过验证的模块证书中取出公钥,解密签名信息,得到出厂时的模块摘要值,并重新计算此时模块的摘要值,两相对比,如果一致说明模块没有被篡改,否则模块的完整性遭到破坏,系统拒绝加载。

(4) 实时检测内核地址数据。内核加载模块大致可分为以下几步:①加载模块文件到内存;②注册加载的模块到相关内核队列中;③执行模块初始化操作;④必要时记录模块间的依赖关系。模块对内核的修改发生在第③步以后,为确定内核不因加载模块发生异常改变,需要此时检测内核关键数据。

系统随开机启动一个用于启动检测程序的守护进程,用于接收内核加载模块进程发来的信号,在没有信号到来时处于休眠状态,接收到信号后启动检测程序,并根据检测结果判断是否发出报警信号。当模块加载完成第③步时,内核加载进程通过进程间的通信机制向守护进程传递请求检测信号,随即守护进程启动检测程序。

内核级Rootkit主要通过重定向中断描述符表、系统调用表、系统调用函数等入侵内核,检测程序主要对相关内核地址进行检查,发现是否有内核地址被重定向。在/boot目录下有一个system.map文件,该文件在编译内核时生成,它包含了系统的内核符号地址。这些符号地址就是检测过程中用来参照的正确地址。/dev/kmem是一个字符设备文件,它保存了系统中所有虚存的一个映像。读取/dev/kmem设备文件,可以获取当前系统中相关内核地址数据。检测步骤如下[5]:①打开/dev/kmem,在/dev/kmem中获取中断描述符表在内存中的首地址,查找sys_call_table 获取系统调用表地址;②比较/dev/kmem中的中断描述符表的地址与system.map中的地址,如果相同则转下一步,否则发出报警信号,并转下一步;③比较/dev/kmem中的系统调用表地址与system.map中的地址,如果相同则转下一步,否则发出报警信号,并转下一步;④比较/dev/kmem中每一个系统调用函数的地址与system.map中的地址,一旦发现地址不一样则发出报警信号,如果相同,则未发现异常,检测结束。

4 结语

本文在Linux系统下实现了一种防范Rootkit入侵的内核模块加载机制。实验证明,该机制能克服传统加载机制安全上的弱点,有效防范内核级Rootkit利用动态加载模块机制入侵内核。如何保护系统关键进程,防止守护进程被恶意中止,以及如何尽可能减小系统性能开销,则有待进一步研究。

参考文献:

[1]赵帅,伍延军,贺也平.基于虚拟机架构的内核Rootkit防范方案[J].计算机工程与应用,2011, 47(11):7274.

[2]Microsoft.Digital signatures for kernel modules on systems running windows vista [EB/OL].http://www.microsoft.com.

[3]LIDS.Linux intrusion detection system[EB/OL]. http://www.lids.org.

[4]陈斌斌,吴庆波,魏立峰. Kylin系统的内核级Rootkit防护[J].计算机工程,2008,34(22):156158.

[5]石晶翔,陈蜀宇,黄晗辉.基于Linux系统调用的内核级Rootkit技术研究[J].计算机技术与发展,2010,20(4):175178.

全文阅读已结束,如果需要下载本文请点击

下载此文档

相关推荐 更多