徐定强
(广东松山职业技术学院,广东韶关512000)
利用虚拟内存快照检测恶意代码
徐定强
(广东松山职业技术学院,广东韶关512000)
据美国计算机安全紧急响应小组US-CERT数据库消息,缓冲区溢出已经成为最关切且极为常见的软件漏洞之一。攻击者经常利用这些漏洞注入恶意的shellcode以控制目标主机。不同于具有独立功能的恶意软件,恶意shellcode是作为正常输入数据伪装在二进制代码片段中的。它们被注入到目标进程的虚拟内存,并劫持进程控制流;更重要的是,它们能够在制造破坏之前,可以实现安全隐藏。当前,已提出了许多针对恶意shellcode的入侵检测方法,从检测的时间上看,大致分为两大类:其一,在处理输入数据的过程中进行检测,简称DDC;其二,处理输入数据之间进行检测,简称DBC。本文将介绍怎么利用这两种方法来检测恶意Shellcode。
虚拟内存;Shellcode;DBC
在入侵检测方法分类中,输入数据在目标进程对其处理(执行)之前对它们进行检测,其大致流程如图1所示。我们对这一类检测又进行了细分:静态分析和动态分析。
图1 基于DBC技术的检测流程
1.静态分析
首先对输入数据进行反汇编,然后通过代码级的模式分析与匹配进行筛选。模式可以是复杂的签名或根据已知的恶意代码进行简单启发式自学习。Toth和kruegel在文章《AccurateBufferOverflowDetectionviaAbstract PayloadExecution》中通过检测NOPsleds的方式来鉴定exploit代码。然而,攻击者可不采用nopsleds技术或者使用多态(polymorphic)技术绕过这种检测(译注:NOP sleds即当shellcode不能准确定位时,为了使执行路径“滑行”到shellcode而填充的一串无意义的指令串,通常为一串连续的NOP指令)。当然总体而言,静态分析还是有效的,只是在检测的准确性和完整性上存在一定的局限;因为二进制混淆技术可有效阻扰代码的模式匹配分析。
2.动态分析
通过网络仿真技术,将输入数据反汇编成一些可能的执行汇编代码链,然后模拟执行每个链。在仿真过程中,若任何一链存在恶意行为,则整个数据块都被列为恶意代码。尽管网络仿真相比静态分析能实现更好的完整性检测,它依旧容易摆脱。其问题在于它没有足够的进程上下文信息,故必须在其初始化和仿真执行时进行假定。
DDC的检测技术是在进程处理输入数据的过程中进行检测,若恶意的运行行为被检测到,进程会执行并发出警报。输入的数据及其目标进程状态日志会被记录下来以作进一步分析。流跟踪(Flowtracking)技术使用一种基于感染的方式来检测输入信息是否为恶意数据。通过地址空间随机化可有效地抵御利用内存错误的攻击方式。操作系统扩展方式即在系统内核或库文件中插入一个检查点以确定调用的脆弱库函数是否安全。总体而言,DDC检测方式是一种基于广泛性使用进程上下文的良好完整性检测,但其检测效率偏低。
与DDC检测相比,DBC检测方法则具有较高的检测效率,但它在检测的全面性上又不如DDC。这是因为DBC检测方法没有使用目标进程在虚拟内存中的运行时信息。
1.系统设计
进程在处理输入数据之前,系统首先对目标进程虚拟内存快照处理,然后将快照信息作为输入参数,送入DBC检测系统,大致流程如图2所示。此时,DBC检测器存在新的数据信息,即目标进程在虚拟内存的运行时信息。虚拟内存快照记录了一个进程的虚拟内存当前状态,包括目标进程的地址空间和寄存器值。此系统中快照以下面两种方式使用:
(1)初始化虚拟执行环境。在目标进程处理数据之前的瞬间,其控制流即被定位到我们的系统。此时已经获取到虚拟内存快照,并立刻激活检测程序,同时初始化输入数据被执行和监控的虚拟环境。快照用来初始化此虚拟环境并提供两个好处。其一,快照对观察输入数据的真实行为至关重要,因为它们诠释了真实的执行流。为了准确地揭露shellcode的行为,此环境尽可能地模仿指定进程处理输入数据的过程。在恶意shellcode里,进程状态可用来重定位执行流。若没有与进程相关的虚拟内存信息,shellcode的执行流可能会发生改变或者甚至被中断。其二,虚拟内存快照很集中,容易获取,而且系统的虚拟环境是轻量型的。在已存在的DBC检测方法中,很难在检测系统中获取到真实的shellcode行为,因为其虚拟内存信息要么被消耗要么被忽略了。
图2 获取快照信息,将其输入到目标进程的检测器中
(2)方便基于系统调用的检测。虚拟内存快照可以让系统及时发现shellcode的其中一种行为,即系统调用的触发,这对检测而言极为重要。恶意shellcode借助系统调用以切换到内核模式运行操作系统相关操作。无论其伪装性多好,它总会使用系统调用来启动攻击行为。不同的系统调用是通过系统调用号和参数来区分的,其存放在寄存器中。如在IA-32体系架构中,系统调用号存放在eax中,其函数参数则存放在ebx、ecx、edx、esi、edi等寄存器中。已存在的DBC检测方法包含静态方法和动态方法,都不可能在检测中跟踪到系统调用,因为它们缺乏必要的寄存器信息。故使用虚拟内存快照,我们可准确鉴别其使用的系统调用,以提高检测精度。下面将根据其工作流来介绍系统的整个设计。
2.系统架构
下面将介绍整个系统架构的设计并提出它的关键模块——shellcode分析器。
(1)结构。整个系统由三个模块组成,如图3所示。第一个模块为协议分析器,可从输入信息中萃取出头部信息,并可依照上层的需求将payload划分成多个子payload。第二个模块为shellcode分析器,主要负责借助虚拟内存快照检测恶意shellcode;其可接收来自协议分析器、外部文件或者同一主机内与本地进程间通信的另一个子进程的sub-payloads。第三个模块为上下文信息的提供者(ContextInformationProvider),充当模拟的执行环境和真实环境之间的一个接口。
图3 系统整体设计
(2)关键模块——shellcode分析器。shellcode分析器结构如图4所示。此模块由指令解密器、指令仿真器、恶意行为检测器、内存仿真系统以及一整套模拟寄存器。指令解密器不断将缓冲区内容翻译成指令,并发送到仿真器。仿真器接收到每一条指令后,它会仿真出一个执行环境,如为内存仿真系统及寄存器提供运行时虚拟环境。此环境被虚拟内存快照实例化,在仿真过程中,虚拟内存或寄存器的访问都被直接定位到内存仿真系统或者寄存器中。
图4 shellcode分析器设计结构
3.工作流分析
Shellcode分析器的工作流程见图5。从输入数据的每个位置看,Shellcode分析器使用虚拟内存快照来模拟解码器指令的执行顺序。快照对观测输入数据的真实行为提供方便,以解释真实执行流。ShellcodeAnalyzer()函数存在两个输入参数:其一为base_address,即将被分析的输入数据起始地址;其二为base_size,即输入数据大小。由快照提供的精确虚拟内存信息可确保Shellcode的执行流不被中断。若执行的子序列为恶意Shellcode,则其使用的所有指令都会在执行流的仿真中检测到,包括Shellcode本身的、由原始消息产生的及其加载到目标进程地址空间的库文件等。故在Shellcode分析器内使用虚拟内存快照进行仿真可用来准确观测多形的变化的Shellcodes及其在群攻击中使用的Shellcode。
图5 Shellcode工作流程代码
hellcode分析器的核心函数为MaliciousInstruction-Seq(),此函数可检测一恶意指令序列。恶意指令序列的工作过程由上面代码的14~34行给出。函数一开始即使用虚拟内存快照初始化仿真环境,然后执行一个while循环以仿真指令序列的执行,直到发生以下错误:其一,检测到恶意行为;其二,遇到非法指令或特权指令;其三,内存非法访问;其四,已执行指令的数量超过了上限。
MaliciousInstructionSeq()函数当遇到条件2和4或者MALICIOUS_SEQUENCE时,则返回BENIGN_SEQUE NCE。在Linux和MSWindows系统里,并不是所有系统调用都会危害目标主机的安全,这依赖于系统调用号和存储在寄存器中的参数。因为快照,系统调用号和其参数可准确获取,此时即可确定当前系统调用是否会危害主机安全。例如,Linux中的11号系统调用execve函数,用于执行某一程序。在指令的仿真中,若其为系统调用指令,且模拟寄存器eax值为11,则系统调用号为11。在校验存储在其他模拟寄存器中的参数后,若其第一个参数为“/bin/sh",则我们可推断此指令具有一定的危害性,因为其作用是试着打开一个root权限的shell。此案例中,系统调用指令将会被列为恶意系统调用。
[1]白南石.关于虚拟内存的一点理解[J].科技信息,2010(27).
[2]王颖,李祥和,关龙,崔宝江.Shellcode攻击与防范技术[J].计算机工程,2010(18).
[3]董鹏程,康绯,舒辉.一种Shellcode动态检测与分析技术[J].小型微型计算机系统,2013(7).
TN
A
1673-0046(2015)4-0167-03