基于API调用行为的二进制通用脱壳方法
注:本人去年参赛的作品,欢迎大家对不足之处提出宝贵的意见,谢谢。
摘要
加壳技术被广泛应用于恶意代码的自我保护,用于对抗躲避反病毒软件的检测,使得反病毒软件检测率大大降低。所以设计一个能够自动化的通用脱壳系统具有重要的理论和现实意义。
基于上述动机,本文设计和实现了基于API调用行为的二进制通用脱壳系统。本系统利用加壳代码"先重建后调用"的API调用行为特征进行脱壳。整个系统采用B/S架构模式。Browser端负责上传样本到Server端以及向用户反馈分析结果;Server端接收样本后,在沙盒环境中动态运行,通过监控"先重建后调用"的API调用行为特征进行动态脱壳。
本文实现了原型系统VirusMore()。实验结果表明,VirusMore能广泛用于不同的软件壳并进行成功脱壳,提高反病毒软件检测恶意代码的准确率和降低对正常程序的误报率。
1.1 背景分析
伴随着信息技术的不断发展,网络给人们带来便利的同时,网络安全威胁问题也日益突出,网络安全风险不断向政治、经济、文化、社会、生态和国防等各个领域传导渗透。据CNCERT抽样监测,2018年,我国境内感染计算机恶意程序的主机数量约655万台[1]。全年捕获计算机恶意程序样本数量超过1亿个,涉及计算机恶意程序家族51万余个[1]。全年计算机恶意程序传播次数日均达500万余次[1]。其中很大一部分样本是通过加壳技术制造出来的变种,恶意代码通过加壳来伪装自己,达到欺骗反病毒软件的目的。
传统反病毒软件依赖于特征码方法来检测恶意代码,它们无法识别加壳恶意代码的变种特征码。安全厂商发布的报告显示现行恶意代码的加壳率高达95%,恶意代码广泛使用加壳技术来保护自己,给反病毒软件带来很大挑战。
现有的脱壳方法一般分为两类:一种是手动脱壳;(只有一句的话就不用用分号)另一种是专用脱壳机。前者依赖于人工的专家经验,耗时长,成本高;后者只能针对某一种壳,通用性差。因此,研究自动化且通用的脱壳方法具有重要的现实意义。
1.2 相关工作
1.2.1 恶意代码检测技术
目前主流恶意代码检测技术主要是静态分析和动态分析两种检测技术。
静态分析方法可以在不实际运行代码的情况下,分析代码特征。早期,研究人员使用静态特征码技术来检测恶意代码,该方法依赖于事先建立的特征码库检测恶意代码,但无法检测未知的恶意代码;后来,研究人员为了弥补静态特征码技术的不足,又提出了静态启发式技术[2],该方法能用于检测部分未知的恶意代码。
动态分析方法主要是通过动态执行被分析程序,监控程序运行行为特征,识别出程序中潜在的恶意行为[2]。
VirusTotal是一个恶意代码在线检测平台。用户提交可疑样本后,VirusTotal使用多种反病毒软件来检测样本。目前,VirusTotal已集成60余种主流的商业反病毒软件。这些反病毒软件采用不同的静态分析和动态分析方法检测恶意代码。相对于单一的反病毒软件,VirusTotal能提供更全面、准确的检测结果。
1.2.2 加壳技术
加壳技术采用一定的加密或压缩算法,对程序源代码进行保护,使其难以被分析。壳一般都是先于被保护程序运行,拿到控制权,在内存中完成解密或解压工作[3]。
壳可分为压缩壳和保护壳[4]。压缩壳帮助缩减PE文件的大小,隐藏了PE文件内部代码和资源,便于网络传输和保存。常见的压缩壳有:UPX、ASpack和PECompat等。保护壳的主要目的不再是用于压缩文件资源,而是用于保护程序被分析和破解。常见的加密壳有:ASProtector、Armadillo、EXECryptor、Themida和VMProtect等。随着加壳技术的发展,两类壳之间的界限逐渐模糊。现在,很多加壳软件既具有压缩功能也具有保护功能。
文献[5]介绍了保护壳使用的保护技术,详细的分析了诸如花指令、SEH技术及IAT加密三种加壳保护手段,并给出了相关实现代码。综合不同的文献,加壳原理主要有以下几类:
(1)反静态分析
通过对代码进行混淆变换,以实现反静态分析的目的。具体的代码静态混淆方式包括加密、压缩、加花、乱序和等效变换等[6]。
(2)反动态分析
通过加入反调试,反跟踪代码,以实现反动态分析的目的。比如,通过识别出一些调试器(OllyDebug)的存在,可实现反调试的目的。
保护壳的大量使用,给反病毒软件带来了很大的挑战,使得VirusTotal等在线网站的检测能力大大降低。如果能对加壳先进行脱壳处理,再提交VirusTotal检测,则能提高其恶意代码的检测能力。
1.2.3 动态脱壳技术
目前已有自动化脱壳的相关方法,主要是通过利用“先写后执行”(Written-Then -Executed)原理来实现脱壳。相关研究包括PolyUnpack[8]、Renovo[9]、OmniUnpack[10]、Eureka[11]、Justin[12]等。“先写后执行”是加壳技术所固有的动态特征,所有的加壳软件都会在内存中恢复被加密或压缩的代码,然后将CPU控制权转交给这些新生成的代码使其执行。然而,加壳程序可使用多层的“先写后执行”来对抗基于“先写后执行”特征的脱壳方法。比如AcProtect壳有多达635 层“先写后执行”行为,并且其原始代码的入口点不在最后一层[13]。
过去二十年,自动化脱壳方法一直依赖的“先写后执行”原理来进行脱壳[14],该方法早已被壳的开发人员所熟知。因此,目前的壳已普遍使用多重的“先写后执行”行为来对抗现有的自动化脱壳方法[15],使其脱壳效率和准确性大大降低。因此,研究如何对抗加壳软件多重的“先写后执行”行为是脱壳领域需要亟待解决的问题。
1.3 特色描述
本系统采用B/S架构,用户只需将样本通过浏览器提交,等待系统显示分析结果即可,无需再本地环境进行。
本系统主要特色如下:
(1)本系统采用B/S架构。脱壳过程在Server端的沙盒进行,用户在Brower端的操作简单且安全;
(2)利用“先重建后调用”的API级行为特征进行自动化脱壳,能对抗采用了多层“先写后执行”的壳,同时,系统提供脱壳后样本供用户下载;
(3)将脱壳后的样本提交壳VirusTotal进行检测,提高恶意代码检测的准确性。
1.4 应用前景分析
根据安全厂商发布的报告显示目前恶意代码的加壳率高达95%[16]。壳的使用大大降低了反病毒软件检测恶意代码的准确性。
如果自动化脱壳系统和反病毒软件相结合,将提高反病毒软件检测恶意代码的准确性,保护用户免遭恶意代码的侵害。相比于传统反病毒软件其优势体现在以下几个方面:1、脱壳也意味这所有通过加壳方式制造出来的海量恶意代码变种都将失去意义,反病毒软件只需比对原始恶意代码特征码既可检测出恶意代码,改变以往通过庞大恶意代码特征码库比对的诟病,可以省去扫描比对的时间,大大提高效率;2、该系统检测是通过云端服务器来实现脱壳,服务器端是通过沙盒环境来对样本进行脱壳,降低了未知程序的安全风险。因为整个过程没有在本地环境中进行,因此不会对本地环境造成任何影响;3、在虚拟环境中运行样本程序,能够监测样本执行时进行了哪些操作,分析完成后可以提供给反病毒软件进行参考,更加精确的分析恶意代码的行为。
综上所述,本系统有有效提高反病毒软件的检测能力,具有广阔的应用前景。
2
2.1 系统方案
本系统采用B/S架构:用户将程序样本通过Browser端提交给Server端。Server端接收到样本后,先对样本进行静态分析,然后将样本放入沙盒环境中运行。在沙盒环境中,本系统监控样本的API调用行为,一旦发现“先重建后调用”的行为特征,则将样本内存的空间转储磁盘文件中,即为脱壳后的样本。Server端将脱壳后的样本以及各项分析结果的反馈给Browser端,供Browser端显示给用户。
2.2 实现原理
本节将对系统实现的关键技术进行介绍。包括基于Detours的动态分析沙盒
、基于“先重建后调用”的API级行为的脱壳方法和基于 VirusTotal 接口的自动化恶意样本检测方法。
2.2.1 基于Detours的动态分析沙盒
本文使用微软的Detours[1]库来实现动态分析沙盒。Detours提供了API Hooking能力,可用于拦截二进制代码中的任意的WIN32API调用。
(1)Detours基本原理
Detours定义了三个重要的函数:
a. Target Function:要拦截的函数,通常为Windows的API;
b. Trampoline Function:Target函数的部分复制品。因为Detours将会改写Target函数头部,所以先把Target函数头部的前5个字节复制保存好,便于以后的恢复;
c. Detour Function:用来替代Target函数的函数。
Detours将Target函数头部的5个字节修改为jmp DetourFunction指令(也是5个字节),该指令把对Target函数的调用引导到自己的Trampoline函数。Trampoline函数首先实现了原Target函数头部的5个字节,然后执行jmp TargetFunction。整个过程如图1所示,图中左边是原始的Target Function和Trampoline Function,右边则是具有API拦截能力的Target Function和Trampoline Function:
图1Detour函数的过程
当被监控进程执行到Target Function时,会首先执行jmp DetourFunction指令(图1),程序控制流会被转移到Detour Function,也就是用户自定义的拦截函数中执行,这时Detour Function就可以执行自己的代码了。Detour Function可以直接返回,也可以调用trampoline Function,trampolineFunction将调用被拦截的原始API,目标API调用结束后又会放回到拦截函数。图2是Detours API拦截的逻辑流程:
图2DetoursAPI拦截的逻辑流程
(2)Detours库重要的函数介绍
a. DetourAttach & DetourDetach
这两个函数就是实际实现API挂钩的(改写头5个字节为一个跳转指令)。DetourAttach用于实现API拦截;DetourDetach用于取消API拦截,恢复原来的API。两个函数都具有两个参数:
第一个参数为被拦截的系统API名。系统原始API函数名使用“Real”前缀来命名;
第二个参数为用户自定义的函数名,用于拦截系统API。用户自定义的函数名使用“Mine”前缀来命名。
b. DetourCreateProcessWithDll
该函数用于实现对目标进程的API Hooking。该函数封装“CreateProcess”,以“CREATE_SUSPEND”方式创建目标进程,然后修改目标进程IAT,把Detoured.dll和本文想要插入的DLL插入到它的导入表,然后再启动目标进程。DetourCreateProcessWithDll的参数是在CreateProcess基础上增加了两个DLL的路径参数,最后一个参数为创建进程的函数指针,默认为CreateProcessA。
2.1.2 基于“先重建后调用”的API级行为的脱壳方法
(1) “先重建后调用”的API调用行为
已有的基于“先写后执行的”指令级特征容易被多层的“先写后执行的”所绕过,因此,研究人员需要寻找新的特征以实现自动化脱壳。本文从一个新的角度重新审视自动化脱壳问题,即API调用行为。IAT(导入地址表)是Windows可执行程序用于查找API地址的数据结构[16][17],对IAT表的静态分析是反病毒软件静态启发式分析的基础[18][19]。
本文对各类加壳程序的深入研究后发现了一个共同的特性:为对抗静态分析,恶意代码的IAT通常会先被加壳软件静态删除;然后在原始代码调用API前进行动态重建。因此,在加壳的恶意代码执行过程中,如果通过重建的IAT来调用API,则表明此时原始代码已经恢复完成。此时对内存进行转储就可以实现脱壳。
Windows操作系统中,重建IAT可以通过API “LoadLibrary”和“GetProcAddress”来实现。本文使用UPX壳保护后恶意样本Conficker来说明IAT重建的过程。原始的Conficker包含287个API(如图3(a)所示)。对于UPX加壳后的样本,UPX压缩代码和数据部分,删除原始IAT,并将UPX壳自身的IAT附加到外壳中(如图3(b)所示)。解压程序的IAT共有来自kernel32.dll等库15个API,其中包括“LoadLibrary”和“GetProcAddress”,它们被用于重建IAT。图3(c)是运行时UPX加壳的样本的内存视图。当控制流到达OEP时,加壳的代码段和数据段已经恢复,并且还重建了Conficker原始IAT表中287个API。值得注意的是,重建的原始IAT和外壳的IAT有两点不同:1)由于外壳程序的功能相对简单,因此它通常比重建后IAT中包含的API更少;2)它们在内存中的地址是不同的。由于原始Conficker代码中的API调用指向的是原始IAT表,为保证其能正常运行,加壳程序需要在原始位置重建Conficker的原始IAT。
图3 加壳后代码的API调用行为
(2) IAT比较
本系统需要将使用Detours监控到当前API调用所引用的IAT和最近一次API调用所引用IAT进行比较,以判断当前调用的API是否来自重建的IAT。
“MyDeleteFile”为用于拦截系统API“DeleteFile”的用户自定义函数,下面以“MyDeleteFile”为例,展示用户自定义函数的工作原理:
算法1 MyDeleteFile算法
1: function MyDeleteFile(lpFileName)
2: if lastIAT = ∅ then
3: routineIAT ← GetUnpackingRoutineIAT()
4: lastIAT ← routineIAT
5: end if
6: currentIAT ← GetCurrentIAT()
7: if currentIAT ≠ lastIAT then
8: OEP ← BacktrackOEP()
9: if OEP ≠ ∅ then
10: Process Dump()
11: lastIAT ← currentIAT
12: end if
13: end if
14: return DeleteFile(lpFileName)
15: end function
MyDeleteFile通过堆栈回溯找到获得当前引用的IAT(第6行),然后根据不同的存储位置或内容比较两个IAT(第7行)。
算法1中使用一个全局变量“lastIAT”,用来表示最后一次重建的IAT。“lastIAT”的初始值是加壳后文件外壳部分的IAT(2-4行)。“currentIAT”为当前API调用所用引用的IAT。如果“currentIAT”与“lastIAT”比较结果不相同,则表示当前的IAT是刚重建的IAT(第7行)。算法1执行回溯搜索OEP(第8行)。如果找到OEP(第9行),则把进程空间内容转储到磁盘中(第10行),然后更新“lastIAT”(第11行)用于下一轮比较。最后算法1调用原始API以继续执行加壳程序(第14行)。
(3)OEP搜索和进程转储
OEP(original entry point)是加壳程序原始代码的第一条指令。如果不能找到正确的OEP会导致脱壳后程序无法执行。已有研究已提出很多搜索OEP启发式规则[20],但它们的搜索空间很大,从而效率低下。本文使用新的启发式规则来缩小OEP的搜索空间。如图4所示,本文首先找到用于重建IAT的最后一次调用的“GetProcAddress”的地址(“T1”),然后找到恢复出的原始代码中第一个API调用的地址(“T2”)。显然,OEP在内存的搜索范围应该在“T1”和“T2”之间。所以,本文从“T2”到“T1”进行回溯,搜索OEP。通过这样的方法可以让OEP的搜索范围大大减少。
进程转储(process dump)是脱壳时另一个需要解决的问题。许多加壳软件使用了各种反转储方法来对抗进程转储。比如将内存中PE头部的访问属性修改为“禁止访问”。因此,当转储PE头部时,转储工具就会崩溃。为此本文采用第三方内存转储工具Scylla。Scylla在转储PE头部前,先将其内存访问属性修改为“可读可写”。
图4OEP搜索
包括Scylla在内的很多转储工具都存在一个问题,就是只转储目标程序的主模块,却忽略动态内存区域(如堆)。因此,本文修改了Scylla代码,使其转储进程空间内容时,不仅转储程序主模块,也转储进程堆空间中的代码。具体过程如图5所示。
图5进程转储
2.2.3 基于VirusTotal接口的自动化恶意样本检测方法
VirusTotal是一个提供免费的可疑文件分析服务的网站。它通过多种反恶意代码引擎扫描文件,以判断文件是否为恶意代码。目前其VirusTotal恶意代码引擎已经多达60余种,大大减少了反病毒软件误杀或未检出恶意代码的几率,其检测率优于使用单一产品。VirusTotal除了可以通过浏览器手动上传样本进行检测以外,还允许用户使用他们提供的API接口自动化上传文件和接收检测结果。因此,本文可以通过调用这些接口来自动化访问VirusTotal。VirusTotal提供了两个URL接口分别用于上传文件和接收检测结果:
https://www.virustotal.com/vtapi/v2/file/scan
https://www.virustotal.com/vtapi/v2/file/report
第一个URL接口是一个post请求,可以将本地文件进行上传,此请求文件大小限制为32MB。自动化上传样本到VirusToTal的Python代码如算法2所示。其中apikey为VirusTotal提供给注册用户的密钥,调用VirusTotal的API接口需使用该密钥。VIRUSTOTAL_FILE_SCAN_URL即为URL接口“https://www.virustotal.com/vtapi/v2/
file/scan”
算法2上传样本到VirusTotal
//apikey为VirusTotal提供的密钥,file_path为样本文件路径
def scan(apikey,file_path):
params = {'apikey': apikey}
// 读取路径中的文件
files = {'file': (apikey, open(file_path, 'rb'))}
response = requests.post(VIRUSTOTAL_FILE_SCAN_URL, files=files, params=params)
第二个URL接口是一个get请求。该请求需要设置一个resource参数,为经过分析的样本MD5,SHA-1或SHA-256。自动化获取VirusToTal分析结果的Python代码如算法3所示。其中VIRUSTOTAL_FILE_URL为URL接口https://www.virustotal.com/
vtapi/v2/file/report
算法3从VirusTotal 中接收分析结果
//apikey为VirusTotal提供的密钥,file_path为样本文件路径
def getFileReportResult(apikey,file_path)
resource = File(self.file_path).get_sha256()
//获取文件哈希值,通过哈希获取扫描的结果
data = {"resource": resource, "apikey": key}
r = requests.get(VIRUSTOTAL_FILE_URL, params=data, verify=True, timeout=int(timeout))
response_data = r.content
2.3 软件流程
2.3.1 整体流程
首先用户通过Browser端提交样本程序,然后Browser端会将样本传递到Server端,所有的分析都在Server端。样本到达Server端,首先通过静态分析获得程序的基本信息;接着样本会交给到Server端沙盒环境中运行,在沙盒环境中进行脱壳和检测行为分析;然后Server端将原样本和脱壳后的样本自动化上传到VirusTotal进行分析并获取分析结果;最后所有的分析结果会保存到数据库中,并反馈给Browser端。用户通过Browser端能浏览所有的分析结果。上述过程如图6所示。
图6系统整体流程
下面分别介绍Browser端和Server端的具体流程。(应向前对其)
2.3.2 Browser端流程
用户上传的样本程序等待系统分析;
查看分析结果和下载样本脱壳文件;
2.3.3 Server端流程
系统接收到用户上传的样本程序并保存到指定文件夹中;
对样本程序的基本信息进行获取:文件大小、文件类型、加壳信息等;
获取程序IAT,然后将样本程序和获取的IAT传递给虚拟机进行分析;
启动Windows虚拟机,并执行脱壳分析脚本将样本程序和相关DLL文件和数据发送到虚拟机中;
启动样本程序,如果pipe收到"PROCESS:"命令,表示恶意程序正在创建子进程或者修改别的进程空间内容,那么这个进程也会被注入本文实现编写的DLL;
通过基于Detours的API Hooking方法对API进行监控;
样本程序运行过程中API的监控会触发脚本依次进行如下操作:
①对当前显示内容进行截图
②对当前程序调用的API进行记录,同时记录其他行为
③获取当前进程的IAT,然后将当前IAT和lastIAT进行比较,如果比较结果不同则继续进行其他处理;如果比较结果相同则转至6),继续运行样本程序
通过启发式的方法来搜索寻到OEP;
通过利用Scylla来转储和修复进程;
将获取到的数据和文件返回给前台进行处理;
执行恢复工作,结束虚拟机进程,执行VboxManage的快照恢复命令;
将文件上传到VirusTotal进行扫描;
获取扫描数据,将数据保存到数据库中和脱壳文件保存到指定文件夹中;
用户查看分析结果时,通过读取数据库中数据向用户展示;
等待下一个分析任务。
2.4主要功能
2.4.1基本信息获取
如图7所示,首先本系统以静态方式分析样本基本信息,包括文件大小、文件类型、是否加壳、MD5和哈希值等。用户可以在下次访问时通过文件名或MD5等来搜索自己曾经提交的样本的分析结果。
图7样本基本信息
2.4.2 静态分析
本系统使用Python第三方库pefile来提取样本PE结构信息,包括PE Information(文件头部信息)、Sections(节)、Imorpts(导入表)等。此外,本系统还会查找PEiD签名,判定样本是否加壳。分析结果如图8所示,其中PEiD查出样本使用了UPX壳进行加壳,同时Imorpts中包含有API "LoadLibraryA"和"GetProcAddress"等。如上文所述(2.2.2节),"LoadLibraryA"和"GetProcAddress"可用于恢复被加壳样本的原始IAT。
图8样本的PE结构静态分析
2.4.3 动态脱壳
本系统将动态脱壳模块位于Server端的Virtualbox虚拟机。此虚拟机基于Detours构建了一个动态分析沙盒。沙盒会拦截样本API调用,插入自定义的拦截代码。拦截代码如算法1所示,一旦发现当前的API调用来自刚重建的IAT,则立即搜索OEP并将进程空间的代码转储到磁盘文件中,该文件即为脱壳后的样本。
2.4.4 恶意程序VirusTotal分析对比
本系统通过调用VirusTotal的API接口实现自动化的上传样本和接收分析结果(如算法2和算法3)。分析结果如图9所示。其中VirusTotal列表示反病毒引擎名称,Signature列的"Clean"代表检测结果为正常,其它值则表示识别出的恶意样本名。例如:AVG的"FileRepMalware"代表反病毒引擎AVG将提交的样本识别为恶意代码"FileRepMalware"。
图9VirusTotal对比分析展示
2.4.5 程序运行截图
为了向用户展示实际程序的运行过程,Server端使用Python的PIL库对样本的运行过程进行截图,并将截图结果保存在Server端的样本数据库中。用户可以通过Browser端浏览Server端的截图结果。截图结果如图10所示。
图10 程序运行截图
2.4.6 数据库存储
为方便用户可以随时查看分析结果,以及适应WEB应用的可扩展的高性能数据存储要求,本系统采用MongoDB数据库来存储分析信息的数据。MongoDB采用文档结构的存储方式,能更便捷的获取数据库中的数据。(可以放一些数据库存储的截图)
第三章 作品测试与分析
3.1 测试方案
本文的测试方案如下:
对于恶意样本脱壳分析后的样本,测试VirusTotal上各反恶意代码引擎检测率是否提高;
正常样本脱壳分析后样本,测试VirusTotal上各反恶意代码引擎误报率是否降低;
对恶意样本进行大规模测试,测试VirusTotal的检测结果。
3.2 测试环境
本文在Ubuntu Server 16.04.1 LTS 32位腾讯云服务器上部署了该系统,主要配置有:
(1)开源虚拟机软件VirtualBox:构建沙盒环境WindowsXP;
(2)WindowsXP系统:样本运行和脱壳的环境;
(3)MongoDB数据库:保存分析数据;
(4)Python 2.7:自动分析脚本的运行环境。
3.3 测试数据
测试方案(1)和测试方案(2)使用单样本进行加壳测试。所使用的样本分别为Windows操作系统下正常程序notepad.exe和从VirusTotal网站上下载的恶意样本WannaCry(如表1所示)。WannaCry为2017年爆发的著名的勒索软件,在全球范围内大规模传播,造成大量用户的经济损失[22]。
表1 单样本测试集
表2 大规模恶意样本测试集
表3 测试壳
3.4 测试过程
因本系统已经部署并备案,故直接进行在线测试。
(1) 将表1中的恶意样本WannaCry用表3中的7个壳分别进行加壳;
(2) 将加壳后的恶意样本上传到VirusMore;
(3) 记录上一步VirusMore的检测结果;
(4) 将表1中的正常程序notepad.exe用表3中的7个壳分别进行加壳;
(5) 将加壳后的正常程上传到VirusMore;
(6) 记录上一步VirusMore的检测结果;
(7) 将表2中的大规模恶意样本测试集分别用表3中的7个壳分别进行加壳;
(8) 将加壳后的恶意样本上传到VirusMore;
(9) 记录上一步VirusMore的检测结果。
3.5 结果分析
测试方案(1)的实验结果如表4所示,其中第一列表示程序的名称,notepad.exe为正常样本,WannaCry为恶意样本。第二列表示样本所使用的加壳工具。PEiD查壳两列中的"√"表示PEiD检测出样本被加壳。VirusTotal两列中的数字表示VirusTotal上判定样本为恶意代码的反病毒引擎的数量。
从表4中的PEiD查壳结果可以看出,加过壳的WannaCry样本均被PEiD识别出加了壳,通过VirusMore脱壳后的样本均被PEiD判定为未加壳。VirusTotal检测的结果中,原始的未加壳的恶意样本有56个标识为恶意程序,但是加壳后检测结果中都有不同程度的下降,表明加壳程序的使用使得反病毒引擎的检测率降低。同时,经过VirusTotal脱壳后的样本的检测率比脱壳前明显升高,表明VirusMore可以帮助VirusTotal提高对加壳恶意代码的检测率。
表4 测试结果
测试方案(2)的实验结果如表5所示。从表5中VirusTotal检测的结果中可以看出,加壳后的正常样本有很多反病毒引擎误报为恶意代码。有研究表明,许多反病毒引擎不具备脱壳能力[23],直接将加过壳的样本判定为恶意代码。与此同时,经过VirusMore脱壳后,VirusTotal误报率显著降低。表明VirusMore可以帮助VirusTotal降低对加壳的正常样本的误报率。
表5 正常样本检测结果
为了进一步测试VirusMore识别加壳后恶意代码的能力,本文选取了10种不同的恶意代码(如表2所示),分别使用7种不同的加壳软件加壳(如表3所示),来测试VirusMore能否帮助VirusTotal识别这些样本。实验结果如表6所示,表中的数字表示,经过ViruMore脱壳后VirusTotal上多少个反病毒引擎能从无法识别样本变成能识别样本。表6表明ViruMore能显著帮助VirusTotal提高对各种加壳的恶意代码的检测率。
表6 加壳的恶意样本大规模测试
第四章 创新性说明
4.1 方法创新
本文查阅大量的文献后发现,目前对于自动化的脱壳方法都是基于"先写后执行"的指令级特征实现。目前的壳普遍使用多层的"先写后执行"来对抗已有的自动化的脱壳方法,使其脱壳成功率和效率大大降低。针对这些,本文从新的视角寻找加壳程序的行为特征,发现了"先重建后调用"的API级行为特征。"先重建后调用"是指在加壳程序会删除恶意代码的IAT以对抗反病毒引擎的静态启发式分析,然后在动态执行原始的恶意代码时会首先重建IAT然后调用其API。因此,一旦发现当前调用的API来自重建后的IAT时,则认为原始的恶意代码已经恢复出来,可以把进程空间的内容转储到磁盘文件中,即为脱壳后样本。
本文方法不需要对加壳后样本进行指令级的监控,以发现"先写后执行"行为特征。只需使用API级的监控,以发现"先重建后调用"行为特征。因此本方法的脱壳成功率和效率都显著高于已有的方法。
4.2 技术创新
为了实现具有较高的可用性、稳定性的脱壳分析系统,本文在多个方面实现了技术创新:
(1)使用Detours库实现了动态分析沙盒,用以监控"先重建后调用"的API行为;
(2)使用VirusTotal的接口实现了自动化的样本提交和分析结果接收。
第五章 实用性说明
已有的恶意代码分析网站VirusTotal上集成了几十种主流的反病毒引擎,比单一反病毒引擎更全面的识别恶意代码。然而,很多反病毒引擎的脱壳能力偏弱甚至不具备脱壳能力[23]。同时,VirusTotal自身也不具备脱壳能力。
本文实现了一个在线脱壳网站()。能够提供在线脱壳和分析服务服务,具体实用功能如下:
(1)通过Submit模块上传样本。用户可以选择上传单个可执行文件,也可以上传一个压缩文件进行批量脱壳。压缩文件内是待脱壳文件进行整合压缩后的文件,系统可以在服务器将压缩文件内的可执行文件提取出来,进行批量脱壳处理;
(2)在Static Analysis模块查看样本详细静态信息。会给用户展示样本文件大小、文件类型、加壳类型、PE文件信息和导入表等。无需用户使用其他工具去查看这些信息;
(3)在Process Dumps本文还提供对脱壳后样本文件的下载。考虑到用户会需要脱壳后的样本,本文可以下载脱壳后样本,出于安全性考虑对于下载文件本文将文件哈希值作为文件名,避免用户下载后打开文件,对主机造成危险;
(4)样本运行截图。为了让用户看到样本程序在运行后的显示,用户可以在分析结果中看到程序在虚拟机中运行的截图,还显示样本对哪些文件进行了操作。让用户更加直观的了解程序显示了什么做过什么;
(5)VirusTotal对比分析。本文将样本脱壳前后VirusTotal扫描的信息在展示也进行对比显示,可以让用户看到有哪些引擎扫描结果前后不同,对不同的结果本文用不同颜色区分更好辨别。
总体来说,本系统VirusMore的脱壳能力能有效帮助VirusTotal提高对加壳恶意代码的检测率,具有很好的实用性。
第六章 总结
恶意代码为了躲避反病毒软件的检测,经过通过加壳的方式来保护自己,会造成反病毒软件的检测率下降。现有的反病毒软件和自动化脱壳方法无法应对使用了多层"先写后执行"的加壳程序带来的挑战。基于上述动机,本文设计和实现了一个基于API级的"先重建后调用"行为的自动化脱壳系统VirusMore。VirusMore为用户提供可视化的应用接口,用户将需要分析和脱壳的可执行程序上传至服务器,等待脱壳和分析结果即可。VirusMore包含有静态分析模块,用于分析样本程序的基本信息、PE文件信息、IAT信息等;VirusMore还将脱壳前后VirusTotal的扫描结果进行对比分析,对样本程序的恶意程度进行一个整体性的评级打分。实验结果表明,VirusMore能帮助VirusTotal中的反病毒引擎提高对加壳恶意代码的检测率和降低对加壳正常样本的误报率。总而言之,本系统具有良好的创新性和实用性。
目前该系统已经在腾讯云上完成部署,任何人都可以通过Web域名()来免费使用VirusMore系统。下一步,本文计划实现VirusMore的自动化Web访问接口,供用户使用python语言自动化的提交样本给VirusMore来脱壳,并接收VirusMore的分析结果,以进一步提高系统的实用性。
参考文献
[1]. 2018年我国互联网网络安全态势综述.国家互联网应急中心. https://www.cert.org.cn, 2019,4-16
[2]. 覃丽芳. 恶意代码动态分析技术的研究与实现[D]. 电子科技大学.
[3]. 郭文,王俊峰.Windows恶意代码动态通用脱壳方法研究[J].四川大学学报,2018, Vol. 55(2):284-285.
[4]. YAO Wei-guang.Research on Software Enclosure Technology[D].Chengdu:Univers-ity of Electronic Science and Technology of China, 2011.
[5]. 张中华,苏志同.PE程序加壳中的反脱壳技术研究[J].北京工业职业技术学院学报,2008,7(03):27-31.
[6]. Cohen F. A cryptographic checksum for integrity protection[J]. Computers & Security, 1987, 6(6):505-510.
[7]. MV Yason,”The Art of Unpacking”,Black Hat Briefings USA, 2007
[8]. Royal P,Halpin M.Dagon D,Edmonds R.Lee W.Polyunpack:Automating the hidden-code extraction of unpackexecuting malware//Proceedings of the 22nd An-nual Computer Security Applications Conference(ACSAC’06).MiamiBeach,FL,USA,2006:289-300
[9]. Kang M,Poosankam P,Yin H.Renovo:A hidden code extractor for packed executables//Proceedings of the 5th ACM Workshop on Recurring Malcode(WORM’07).Alexandria,VA,USA,2007:46-53
[10]. Martignoni L.Christodorescu M.Jha S.Omniunpackl Fast,generic.and safe unpacking of malware//Proceedings of the 23rd Annual Computer Security Applications Conference(ACSAC’07).Miami Beach,FI,USA,2007:431-441
[11]. Sharif M,Yegneswaran V,Saidi H,Porras P,Lee W.Eureka l A framework for enabling static malware analysis//Proceedings of the 13th European Symposium on Research in Computer Security(ESORICS’08).Malaga,Spain,2008:48l-500
[12]. Guo F,Ferrie P,Chiueh T.A study of the packer problem and its solutions//Proceedings of the 11th International Symposium on Recent Advances in Intrusion Detection(RAID’08).Cambridge,Massachusetts,USA,2008:98-115
[13]. Ugarte-Pedrero X, Balzarotti D, Santos I, et al. SoK: Deep packer inspection: A longitudinal study of the complexity of run-time packers[C]//2015 IEEE Symposium on Security and Privacy. IEEE, 2015: 659-673.
[14]. Polino M, Continella A, Mariani S, et al. Measuring and defeating anti-instrumentation-equipped malware[C]//International Conference on Detection of Intrusions and Malware, and Vulnerability Assessment. Springer, Cham, 2017: 73-96.
[15]. Bonfante G, Fernandez J, Marion J Y, et al. CoDisasm: medium scale concatic disassembly of self-modifying binaries with overlapping instructions[C]//Proceedings of the 22nd ACM SIGSAC Conference on Computer and Communications Security. ACM, 2015: 745-756.
[16]. 余三超. 基于虚拟机的通用自动化脱壳系统[D]. 电子科技大学.
[17]. 嵇海明, 杨宗源. PE文件格式剖析[J]. 计算机应用研究, 2004, 21(3):165-166.
[18]. 庞立会. PE文件动态加壳技术的研究与实现[J]. 计算机工程, 2008, 34(19):160-162.
[19]. 冯本慧, 王加阳. 一种基于静态API调用与集成学习的恶意代码检测技术[J]. 科技信息, 2013(9):32-32.
[20]. 段海新等,计算机病毒防范艺术. Szor P,The art of computer virus research and defense[M]. 2007.
[21]. 王志, 贾春福, 鲁凯. 基于环境敏感分析的恶意代码脱壳方法[J]. 计算机学报, 2012, 35(4):693-702.
[22]. WannaCry,https://baike.baidu.com/item/WannaCry/20797421?fr=aladdin
[23]. 代码战争:伪装和狙杀,从“壳”到“病毒混淆器”, https://www.freebuf.com/articles/system/112631.html