本文将向读者介绍一种通过处理器的调试机制来实现Rootkit的隐形的技术。这种技术的特点是,无需利用系统的缺陷,直接处理器的正常功能就能达到隐形的目的。本文将以Linux系统为例来介绍如何实现基于调试寄存器的隐形方法。
一、概述
几年来,用于在攻陷的机器上实现隐形技术和方法越来越多,让人目不暇接。其中,有一些直接篡改系统调用表,有一些修改中断处理程序,凡此种种,在此不再一一列举。不过,这些方法的共同之处在于,都以可见的形式修改了底层的操作系统,这使得它们很容易被发现。
本文中,笔者利用调试机制这一x86平台的共同特性,用内核级Rootkit实现了终极的隐形。虽然该方法通用于所有IA-32兼容平台,但我们这里以Linux操作系统为例,讲解如何在不碰钩子技术的各种“传统”目标(如系统调用表、中断处理程序等)的情况下拦截正常执行流程的技术。 实际上,这种隐形技术是如此高超,以至于还没有人发现我们的存在。
在本文中,当我们说“调试器”时,实际上指的是只能从ring 0访问的IA-32的调试机制,对于用户空间的调试程序来说,是无法利用这个机制的,只有某些内核调试工具才能使用这个机制。
二、处理器的调试机制
为了让开发人员过得更轻松些,Intel公司引入了一个机制来处理调试过程。按照Intel公司的用户手册的说法,“IA-32架构提供了大量的调试设施,供调试代码、监视代码执行和处理器性能之用。这些设施对调试应用程序软件、系统软件和多任务操作系统都是非常重要的 ”。开发人员可以通过一组专用寄存器(称为调试寄存器,从DR0至DR7)来使用该机制,这样他们就可以根据内存地址来设置硬件断点了。一旦执行流到达带有断点标记的地址,控制权就会交给调试中断处理程序(INT 1),该处理程序继而调用do_debug()函数(定义在/i386/kernel/traps.c文件中)来处理引起异常的实际情况。
可以通过调试寄存器(DB0~DB7)和两个与模式特定的寄存器(MSR)来访问这种调试支持。对本文而言,我们只需关心调试寄存器就行了。这些寄存器存放的是内存地址和I/O位置,我们将其称之为断点。断点既可以是用户在程序中选定的位置(指令断点),也可以是内存中的数据存储区(数据断点),还可以是指定的I/O端口(I/O断点),程序员或者系统设计人员通常希望程序在这些指定的地方停下来,以便调用调试软件来检查处理器的状态。
当内存或I/O设备访问某个断点地址时,就会引起一个调试异常(#DB)。我们可以进一步为断点规定引起中断的具体的内存访问方式或者I/O访问方式,例如一个内存读和/或写操作或者I/O读和/或写操作(即以规定之外的方式访问该断点时不会引起中断)。调试寄存器同时支持指令断点和数据断点。MSR是从P6系列处理器开始引入IA-32架构的,它用于监视分支、中断和异常,并记录下最后分支、中断或者异常所使用的源地址和目的地址,以及最后中断或者异常之前发生的分支的源地址和目的地址。
共5页: 1 [2] [3] [4] [5] 下一页 | |||||||
|