Popek和Goldberg指出虚拟机监控器应当满足以下三个条件:
(1)虚拟机监控器应当向所有虚拟机中的操作系统提供相同的应用程序二进制接口(Application binary interface, ABI)。
(2)虚拟机监控器向虚拟机展示出来的硬件视图与物理机器相比,性能损失很小。
(3)虚拟机监控器管理着所有的系统资源。
虚拟机监控器要满足以上条件,需要硬件体系结构能够“虚拟化”,也就是说每条指令需要一个明确的特权级别。虚拟机监控器可以执行特权级指令,而用户程序和虚拟机只能执行非特权指令。这样的限制使得虚拟机监控器能够维持其系统资源的控制权,允许虚拟机用陷入(trap)-模拟(emulate)的方式来完成虚拟化过程。当执行非特权指令的虚拟机试图执行特权指令时,会陷入到虚拟机,交给虚拟机监控器去执行,虚拟机监控器执行特权指令后将结果返回给虚拟机,制造出一种虚拟机直接访问硬件的假象。
Rootkit主要采用两种方式进行攻击:内核钩子和内核模块注入。
内核钩子主要有三部分组成:要钩取的函数,替代要钩取函数的函数和系统调用表。
内核模块又叫可加载内核模块(Loadable Kernel Module, LKM),是Linux内核向外部提供的一个插口,内核模块扩展了Linux内核的功能。Linux内核需要哪些内核模块,就将其加载到内存中使用,不需要时就将其卸载,并且不需要对操作进行重启。
内核模块以二进制文件的形式存储在磁盘上,可以在系统运行过程中的任何时刻加载。内核模块一旦加载到内核内存中,就具有了Linux内核的所有权限,正是由于内核模块具备的这种特性,很多Rootkit以内核模块的方式运行,以达到攻击目的,并且不易被安全软件发现。
Linux内核维护了一个模块列表的数据结构,它与进程列表类似,也是一个双向链表。模块列表中使用一个包含模块名字的字符串唯一的表示该模块。为了实现Rootkit攻击痕迹隐藏(如文件、进程等),攻击者通常利用LKM向内核插入钩子。在用户空间执行lsmod命令就可以查看当前的模块列表,这是新加载的内核模块会在/proc/modules文件中留下信息,而lsmod命令就是读取/proc/modules。为了避免用户发现可疑的内核模块,攻击者
通常会采取一些模块隐藏措施。
一般主要有两种方式来实现内核模块的隐藏:第一种方法是把查询模块信息的系统调用sys_query_module()替换掉,在新的系统调用处理函数中首先调用原来的sys_query_module()[54],得到所有的模块信息,然后将需要隐藏的模块信息过滤掉,最后将结果返回给该系统调用的使用者;另外一种方法就是直接将恶意模块从内核模块链表中移除,但并没有将它从内核内存中卸载。由于模块加载时该模块的输出变量已被其他内核模块所引用,因此在模块链表中移除该模块并不会影响其功能。
Rootkit检测技术
(1)基于特征码检测方法
(2)基于完整性的检测方法
(3)基于污点传播机制的检测方法
(4)可执行路径分析方法
基于虚拟化技术进行安全监控
基于虚拟化技术的安全监控是利用虚拟机监控器来隔离特定的安全监控工具,这样既可以保护安全监控工具不被虚拟机进破坏,又能降低了维护开销。
从安全监控的实现方式的角度看,基于虚拟化技术的安全监控研究可以分为两类:内部监控和外部监控。
KVM基本结构主要有两部分组成。一个是KVM Driver,它负责创建虚拟机,分配虚拟内存,读写虚拟CPU寄存器以及运行虚拟CPU等。另外一个部分是经过稍微修改过的QEMU,它主要用于模拟PC硬件的用户空间组件,提供I/O设备模型以及访问外部设备的途径。在KVM虚拟化平台中,通常将虚拟机监控器称为宿主机,运行在其上的虚拟机称为客户机。