Android平台恶意代码检测通用脱壳机的设计
2017-04-22黄灿邱卫东王力
黄灿, 邱卫东, 王力
(上海交通大学 电子信息与电气工程学院,上海 200240)
Android平台恶意代码检测通用脱壳机的设计
黄灿, 邱卫东, 王力
(上海交通大学 电子信息与电气工程学院,上海 200240)
随着移动互联网的普及,以及Android平台所占份额的逐步提高,Android平台应用程序的安全性尤为重要。因此设计了一个基于Android平台恶意代码检测的高效通用脱壳机,并辅以静态恶意代码的检测。详细介绍了Android平台主流加固技术以及该通用脱壳机的实现原理和方法,结果表明,该脱壳机能够应对市面上几乎所有的主流加固厂商。
恶意代码检测; 脱壳机; 加固; 静态分析
0 引言
近年来智能移动终端和移动互联网的发展如火如荼,由于Android系统的开放性,现今越来越多的智能终端上都运行着Android系统,Android系统是当前占有市场份额最大的智能移动终端操作系统,安全研究人员亦逐渐聚焦到Android系统应用程序的安全研究上来。对于恶意代码检测而言,目前学术界将其分为静态检测和动态检测两个方向。在静态检测领域,安全研究人员开发出了基于代码相似度检测的ViewDroid[1]、基于组件的Chex[2]、基于数据流的SCanDroid[3]和基于控制流图搜索和数据标记的DroidChecker[4]等工具;在动态检测方面,也有TaintDroid[5]之类的基于污点跟踪技术的隐私泄露监控系统和VetDroid[6]、DroidScope[7]、CopperDroid[8]之类的细粒度动态行为跟踪系统等。
其中在Android平台静态恶意代码检测中最知名的就是Androguard[9],很多优秀的恶意代码检测系统都是基于它进行开发的,同时提供了很多辅助分析模块供分析人员使用。之后安全研究人员陆续开发了FlowDroid[10]、RiskRanker[11]、DroidMOSS[12]等等静态分析系统。这些静态分析系统都利用了Android平台使用的Java代码较为容易反编译的特点,从代码片段入手进行高效快速的恶意代码检测。但是随着Android平台软件保护技术的发展和普及,越来越多的恶意代码对自身的加固保护进一步增强,且同时由于混淆、花指令和代码加密等加固技术的不断加强,导致静态工具检测面临诸多困难,难以实现大规模部署的应用,所以当前的静态分析系统往往需要一个功能强大的通用脱壳机加以辅助。
本文结合当前Android平台主流加固技术设计并实现了一个针对应用层的高效率通用脱壳机,本文的组织架构如下:
第二章详细介绍了Android平台应用层加固的背景知识,具体包括Android DEX文件的加载机制,应用层加固的主要类别以及编写脱壳机所面临的主要困难。
第三章设计并实现了该通用脱壳机,并详细阐述了反-反模拟器模块、DEX应用层脱壳的工程实现细节和相关原理等。
第四章对脱壳机的覆盖面和时间效率方面进行了全方位的测试,对实验结果进行分析,验证系统性能。
本文最后指出了当前脱壳机的优缺点,提出了改进方法,并说明了下一步的研究方向。
1 加固背景知识
Android应用程序是APK文件,本质是一个ZIP的压缩文件,开发人员编写的应用层代码会被编译成Dex文件并打包进APK文件中。由于Java应用层代码容易被反编译,被攻击者破解,所以开发者为了保护应用程序,对抗逆向分析,而对应用进行加固混淆等处理,后文的分析均是基于Android 4.1.2的Android源码。
1.1 Android文件加载机制
在Android系统中加载APK一般有两种方式,一种是通过文件的方式加载,另一种是通过字节流的方式加载,这两种方式本质上是一致的,只是数据的存储方式不同。在Android系统中,每个类加载创建进程时都会通过类PathClassLoader进行加载,同时开发者也可以通过DexClassLoader动态加载额外的dex文件。PathClassLoader和DexClassLoader都继承自BaseDexClassLoader这个基类,二者会生成一个DexPathList对象,在DexPathList的构造函数中调用makeDexElements()函数,继而在makeDexElement()函数中调用LoadDexFile()对dex文件进行处理 ,LoadDexFile()最终返回DexFile对象。LoadDexFile()函数的执行细节是通过JNI进入原生层,调用原生层的相关函数进行处理的。
进入原生层之后,针对DEX文件和二进制字节流,系统分别提供了DvmDexFileOpenFromFd和DvmDexFileOpenFromPartial这两个函数进行处理,这两个函数的最终目的都是构造一个DexOrJar结构体,并通过JNI把该结构体的地址保存到DexFile的私有成员变量mCookie中,这一过程结束之后退回到应用层,基本上完成了一个Android类的加载过程,后续系统模块中的Dex监控模块和DexDump模块都是基于此加载流程实现的。
1.2 加固技术
应用层加固一般采用采取自保护变形技术[13]对自身进行保护,目前加固变形技术包括文件整体加密、字节流加密、关键信息破坏、字节码抽取、字节码变形和混合方案等。
文件整体加密是针对classes.dex文件进行加密,并以资源文件的方式保存在系统的某处,当进程加完载壳程序后,壳程序会从资源文件处解密dex文件,再将解密后的dex文件保存在文件系统某处,最终动态加载进内存。
字节流加密所通过二进制字节流的方式加载dex文件,其解密过程是在内存中完成,原始的dex文件不会保留在文件系统。
关键信息破坏则是同时使用上面两种加壳方案,解压后的dex文件最终会完整的存放于内存的某个连续区域,因此只要找到其起始地址和长度,分析人员就能从内存中完整的dump出classes.dex。但对于Dalvik虚拟机而言,要正确执行一个dex文件并不需要该文件的结构信息,所以可对dex文件的结构信息进行破坏,从而影响分析人员对dump下来的文件进行静态分析。
字节码抽取是关键信息破坏方案的进一步发展,主要是把classes.dex的内容分散存放。这个技术利用了dex文件的数据是使用偏移值进行读取的原理,针对这种情况,分析人员必须对当前进程中分布在不同区域的数据进行重建,重新构造出一个连续存储的dex文件,并保存到文件系统。
字节码变形的主要目的有两个,一个是隐藏字节码,二是提高静态分析的难度。各家加固服务技术实现细节千差万别,但技术原理类似,其一是修改Encode Method结构的access_flags和code_off字段,使原来的方法变成native方法。当该方法被执行时,通过JNI机制,就会先执行壳的逻辑,壳会还原Method属性,然后通过JNI所提供的接口,重新执行原来的字节码。对于这种方式,如果用静态分析工具分析,会发现那些被标记为native的方法只剩下方法声明,从而达到隐藏字节码的目的。
其二是在加固时,先为选中的方法添加一个跳转方法,这个跳转方法的DexCode和原方法完全相同,而原方法按方式一处理成native方法。当执行到壳逻辑时,壳再通过JNI所提供的接口,调用跳转方法。这种方式改变了原程序逻辑流程,增加了分析的困难。
混合类型是以上所述方法的综合体,文件结构更加碎片化、字节码变形更加多样化、加密更加精细化,因此分析难度更高。
1.3 脱壳机面临的困难
目前加固服务提供商一般还会结合其他防御手段,比如防注入、反调试、反模拟器、防dump等,这些防御手段的混合使用,进一步提高了脱壳的难度。
1) 防注入技术[14]可以有效避免内存dump,关键函数被挂钩等,比如Apkprotect[15]会遍历检查/proc/self/maps的加载列表,如果发现未知的dex文件被加载,则直接退出进程。
2) 反调试[16]可以勘察出当前进程是否被调试,一旦发现被调试则直接退出进程。主要分为:对调试器监测,进程运行状态检测以及多个进程相互ptrace[17]实现反调试。
3) 反dump技术主要有如下两种方法。一种是利用Inotify机制,该机制提供了监视文件系统的事件机制,可用于监视个别文件,或者监控目录。二是对read函数等进行hook,检测read函数当前读取的数据是否属于关键内存区域,从而阻止内存dump。
4) 反模拟器技术主要用于检测当前运行环境是否为模拟器,常见的模拟器检测技术主要分为基于特殊文件的模拟器检测技术以及基于系统特定属性的模拟器检测技术两种。在Android模拟器中存在一些独属于模拟器的特殊文件,应用程序可以通过检测当前系统中是否含有这些特殊文件来确定应用是否处于模拟器的运行环境,同时模拟器中Android系统的一些特定属性与实体机不同,因此也可以利用系统中的这些特殊属性进行检测,详细的特殊文件和属性,如表1所示。
表1 模拟器检测相关文件和属性列表
2 脱壳机设计与实现
综合之前所述,本文设计了一个针对应用层的通用脱壳机,从上而下分为DEX Dump应用层、反-反模拟器模块和DEX加载监控模块、API HOOK框架层和QEMU Android模拟器层五个层次,脱壳机的整体架构,如图1所示。
图1 脱壳机架构
对于DEX Dump应用层而言,当壳程序完整解固后,在当前进程中必然保存着完整的dex信息(或者部分信息被篡改,但依然可以推断出原始信息),因此只要成功注入到目标进程,通过收集运行时的关键信息,再利用Memory Dump或重建的技术手段,就可以把原始的dex数据提取出来。本文基于Cydia Substrate框架,在dex加载的合适时机添加监控点,收集脱壳所需的关键信息。同时考虑到某些加固方案可能会在加载后做一些内容恢复或替换的操作,因此脱壳机会在整个应用都正常运行起来,待“壳”的修复动作达到稳定之后再进行脱壳,这样就完成了应用层的脱壳。
同时为了方便在模拟器上进行后续工业级大规模的部署,本文开发了反-反模拟器模块,该模块主要用于隐藏模拟器的特殊文件和属性,以应对模拟器的检测,整体基于API HOOK框架层而实现。
API HOOK框架层主要是为上层模块提供服务,涉及Java Hook和Inline Hook等技术,该模块整体基于Cydia Substrate框架实现。另外在这个模块额外添加了过滤策略,过滤掉系统内置的应用,把作用范围限制在本文关注的样本进程中,该过滤策略作用于Hook Layer以上的所有模块。
QEMU Android模拟器层主要是为后续大规模部署、反-反模拟器模块等服务。
由于该脱壳机是面向海量样本的,且要求达到完全自动化的并发执行任务,脱壳机采用Google原生Android模拟器作为工作环境,模拟器硬件配置,如表2所示。
表2 模拟器硬件配置
2.1 反-反模拟器模块
加固软件会检测模拟器系统特殊文件和系统特殊属性,而这些操作都需要通过调用libc.so库中的fopen等API函数读取系统文件属性来做判断,考虑到API函数执行的正常流程是先从API到ABI再到内核层,本模块采取的方案是HOOK ABI层次,由于ABI是所有函数执行必须经过的层次,通过HOOK ABI调用接口,使其先执行自定义的系统函数,再返回正常的后续逻辑,这样可以避免诸多限制和制约。
本模块最后通过LKM实现对Linux内核功能的扩展,通过在ABI层面HOOK模拟器常用的系统库函数而得以实现该模块。
2.2 DEX应用层
针对DEX加载监控模块,本系统主要是在APK加载流程中添加了两个监控点:BaseDexClassLoader的构造函数和dvmDexFileOpenPartial函数。通过HOOK BaseDexClassLoader的构造函数,可以得到所有继承于此类的BaseDexClassLoader以及子类实例引用。通过这些实例引用,可以获得DexOrJar指针,为此本脱壳器设计了类ClassLoaderDumper,该类负责存储这些实例引用对象。
正常的加载流程只能加载Dex文件,而通过dvmDexFileOpenPartial可以加载Dex二进制字节流,因此通过这个函数,可以获取保存Dex数据的内存地址Addr,数据长度Len和构造DvmDex结构的地址,本脱壳器设计了类HookDexDumper负责存储这些数据应用层脱壳所涉及到的几个关键类之间的联系,如图3所示。
Dex Dump是应用层DEX脱壳机的核心部分,一共包含5个处理流程,并封装成5类,它们分别是HookDexDumper、DexOrJarDumper、ClassLoaderDumper、DirectlyDumper和RebuildDexDumper,且都继承自类BaseDexDumper。这5类所完成的流程互相依赖,而且每个流程都会有相应的输出,当所有的流程运行完毕之后,会得到一个或多个dex文件,紧接着脱壳机会进行分组,并从每组中提取出最优的文件。
HookDexDumper类,当监控到dvmDexFileOpenPartial函数被调用时,脱壳机会马上生成HookDexDumper对象,HookDexDumper根据传入的addr和len,把dex的所有数据复制保存到copyData_,这样做主要是考虑到后面dex数据有被篡改的可能,然后HookDexDumper会先把“壳”过滤掉,然后将copyData_写入文件系统。
DexOrJarDumper类负责处理DexOrJar结构。其中dump的过程相比于其他的几个流程会复杂一点,先通过pDvmDex获取dex在内存的中开始地址addr和size。如果是dex文件,则检查dex文件头是否合法,主要是检查是否被篡改,如果合法则启用DirectlyDumper流程。考虑到有字节码抽离的情况,因此紧接着再启用RebuildDexDumper流程。如果是odex文件,过程与dex文件类似。
ClassLoaderDumper类。任何继承自BaseDexClassLoader的子类在创建实例时都要触发ClassLoaderDumper类的创建。该类主要保存Java实例的引用。ClassLoaderDumper的Dump的逻辑很简单,先从classloader_成员变量中获取所有DexOrJar的地址,然后调用DexOrJarDumper的Dump方法。
DirectlyDumper主要根据传入的addr和size把dex写入文件系统,其过程跟HookDexDumper流程相比 主要是多了dex和odex的判断,影响最终写入文件的命名后缀。RebuildDexDumper类比较复杂,除了解决字节码抽离的情况,同时在重建的过程中能够修正被某些刻意篡改的数值。
图3 应用层关键类关系
这5类所完成的流程相互依赖,并且每个流程都会产生相应的输出,当所有的流程运行完毕之后,便会得到多个dex文件,这边是DEX应用层所输出的结果,DEX应用层类协作脱壳的完整流程图,如图4所示。
图4 应用层类协作脱壳流程
3 试验与讨论
3.1 脱壳机有效性分析
使用此脱壳机对市场上绝大部分加固厂商的普通版加固产品进行脱壳测试,测试结果,如表3所示。
表3 脱壳机效果展示
从上面的结果可以看出,本文设计的脱壳机能够应对市面上所有主流的加固厂商。
3.2 脱壳机效率
脱壳机的效率主要参考单个加固样本的平均脱壳时间。脱壳时间是指从脱壳机获取样本后开始准备脱壳任务开始,但脱壳完成输出脱壳后样本文件为止。中间主要包括启动脱壳机时间,安装待脱壳样本事件以及脱壳时间。其中启动脱壳机时间一般固定不变,而后两者会根据具体样本的不同变化而变化。通过对随机抽取10个加固样本,分别对它们进行脱壳处理,各个样本的脱壳时间,如图5所示。
图5 脱壳时间
从图5可以看出,每个样本的脱壳时间并不相同,这主要跟样本本身的大小有关。一般情况下,样本越大,其安装时间就越长,脱壳时间也越长,其最终所需要的脱壳时间就越大。估算出平均需要的脱壳时间为132.9秒,那么一台模拟器一天可以脱壳650个样本,假设每台主机可同时运行6台模拟器,共10台主机,那么一天一共可以完成39 000的脱壳量,足够覆盖每天的新增样本数。
4 总结
本文设计了一个基于Android平台恶意代码检测静态分析的通用脱壳机,以辅助静态分析能够分析加固后的应用程序,该脱壳机能够应对市面上绝大部分代码在应用层采取的加固技术,且脱壳迅速,从而极大的提高了静态检测的准确率和效率。
由于本系统未深入探讨原生层的脱壳问题,但考虑到双层协作脱壳是后续的主流,因此原生层的脱壳问题值得进一步研究和关注。后期可以借鉴Windows平台PE文件格式的一些成熟检测技术,拓宽对原生层脱壳的处理。
其次脱壳与恶意代码检测息息相关,未来可以考虑将本系统与恶意代码检测相结合,脱壳后运用大数据和机器学习的方法建立恶意代码行为模式,进行漏洞探测等研究,以便建立更加智能化的恶意代码检测机制,提供更加精确的查杀结果。
[1] Zhang F, Huang H, Zhu S, et al. ViewDroid: towards obfuscation-resilient mobile application repackaging detection[C]//Proceedings of the 2014 ACM Conference on Security and Privacy in Wireless & Mobile Networks, 2014: 25-36.
[2] Lu L, Li Z, Wu Z, et al. Chex: statically vetting android apps for component hijack-ing vulnerabilities[C]//Proceedings of the 2012 ACM Conference on Computer and Communications Security, 2012: 229-240.
[3] Fuchs A P, Chaudhuri A, Foster J S. SCanDroid: Automated security certification of Android applications[R]. CS-TR-4991 of University of Maryland Tech, 2009:1-16.
[4] Chan P P F, Hui L C K, Yiu S M. Droidchecker: analyzing android applications for capability leak[C]//Proceedings of the Fifth ACM Conference on Security and Privacy in Wireless and Mobile Networks, 2012: 125-136.
[5] Enck W, Gilbert P, Han S, et al. TaintDroid: an information-flow tracking system for realtime privacy monitoring on smartphones[J]. ACM Transactions on Computer Systems (TOCS), 2014, 32(2): 5.
[6] Zhang Y, Yang M, Xu B, et al. Vetting undesirable behaviors in android apps with permission use analysis[C]//Proceedings of the 2013 ACM SIGSAC Conference on Computer & Communications Security, 2013: 611-622.
[7] Yan L K, Yin H. Droidscope: Seamlessly Reconstructing the OS and Dalvik Semantic Views for Dynamic Android Malware Analysis[C]//the 21st USE-NIX Security Symposium (USENIX Security 12), 2012: 569-584.
[8] Reina A, Fattori A, Cavallaro L. A system Call-centric Analysis and Stimulation Technique to Automatically Reconstruct Android Malware Behaviors[J]. EuroSec, 2013: 1-6.
[9] Desnos A. Androguard-Reverse Engineering, Malware and Goodware Analysis of Android Applications[EB/OL].http://code.google.com/p/androguard,2013-03-26/2016-12-22.
[10] Arzt S, Rasthofer S, Fritz C, et al. Flowdroid: Precise context, flow, field, object-sensitive and lifecycle-aware taint analysis for android apps[J]. ACM SIGPLAN Notices, 2014, 49(6): 259-269.
[11] Grace M, Zhou Y, Zhang Q, et al. Riskranker: Scalable and accurate zero-day an-droid malware detection[C]//Proceedings of the 10th International Conference on Mobile Systems, Applications, and Services, 2012: 281-294.
[12] Huang H, Zhu S, Liu P, et al. A Framework for Evaluating Mobile APP Repackaging Detection Algorithms[C]//International Conference on Trust and Trustworthy Compu-ting. Springer Berlin Heidelberg, 2013: 169-186.
[13] Schlegel R, Zhang K, Zhou X, et al. Soundcomber: A Stealthy and Context-Aware Sound Trojan for Smartphones[C]//Proceedings of the 18th Annual Symposium on Network and Distributed System Security (NDSS), 2011, 11: 17-33.
[14] Lin J C, Chen J M. An automatic revised tool for anti-malicious injection[C]// Proceedings of the 6th IEEE International Conference on Computer and Information Technology, 2006: 164-164.
[15] Love R. Kernel korner: Intro to inotify[J]. Linux Journal, 2005, 2005(139): 8.
[16] Gagnon M N, Taylor S, Ghosh A K. Software protection through anti-debugging[J]. Security & Privacy, 2007, 5(3): 82-84.
[17] Dike J. A user-mode port of the Linux kernel[C]//Proceedings of the 2000 Linux Showcase and Conference. 2000, 2(1): 2.1.
Design of the Universal Unpacker for Malicious Code Detection on the Android Platform
Huang Can,Qiu Weidong,Wang Li
(Shanghai JiaoTong University, School of Electronic Information and Electrical Engineering, Shanghai 200240, China)
With the popularity of mobile Internet and the growing share of the Android platform, the safety of the application on the Android platform has become an important issue. Hence, this paper has designed an efficient universal unpacker for the malicious code detection based on the Android platform in aid of the static analysis. The mainstream reinforcement technologies for the Android as well as the principle and method of realizing the universal unpacker have been illustrated. It is found that the unpacker can satisfy the needs of almost all mainstream reinforcement companies in the market.
Malicious code detection; Unpacker; Reinforcement; Static analysis
黄 灿(1991-),男,硕士研究生, 研究方向:移动安全。 邱卫东(1973-),男,教授,博士,研究方向:计算机取证、密码分析破解、密钥防护及电子信息对抗。 王 力(1993-),男,硕士研究生,研究方向:移动安全。
1007-757X(2017)04-0048-05
TP311
A
2016.09.06)